Writing.
Long-form deep-dives, short notes, and the occasional retro from building this portfolio.
Featured posts

Signals, effects, and the death of the async pipe
I removed the last async pipe from a production app. Why signals quietly took over the parts of my templates observables used to own — and the few places I still reach for RxJS on purpose.

Angular SSR Hydration: The Transfer-Cache Pattern
The transfer cache solves Angular SSR's double-fetch flash — but it ships a per-user bug if you don't filter it. Here's the discipline I've landed on after a year of SSR work.
Zoneless Angular: what changes, what doesn't
Going zoneless either "changes everything" or "changes nothing" — both wrong. What actually changes after migrating an app off Zone.js, what stays identical, and the three things that surprised me.

All posts
Zoneless Angular: what changes, what doesn'tGoing zoneless either "changes everything" or "changes nothing" — both wrong. What actually changes after migrating an app off Zone.js, what stays identical, and the three things that surprised me.
Signals, effects, and the death of the async pipeI removed the last async pipe from a production app. Why signals quietly took over the parts of my templates observables used to own — and the few places I still reach for RxJS on purpose.
A pragmatic guide to Nx module boundariesTags are not labels — they are a type system for your architecture, and the lint rule is the type-checker. The constraints I land on in every monorepo, and why "feature never imports feature" pays the most.
The PR review checklist I actually useAfter a few thousand reviews: scope, read the test first, look for the thing that is not there, names, test altitude, and "could I debug this at 2am?" — plus what I never comment on.
Angular SSR Hydration: The Transfer-Cache PatternThe transfer cache solves Angular SSR's double-fetch flash — but it ships a per-user bug if you don't filter it. Here's the discipline I've landed on after a year of SSR work.
TIL: CSS :has() as a parent selector in production
TIL: Postgres partial unique indexes for soft delete
Tại sao tôi viết test trước khi viết codeViết test trước không phải vì sách bảo thế — mà vì nó buộc tôi hiểu mình đang làm gì trước khi gõ dòng code đầu tiên.
Quy trình review code của team mìnhKhông quá nặng để làm chậm mọi người, nhưng đủ chặt để bug không lọt ra production. PR nhỏ, review nhanh, comment vào code chứ không vào người.
Retro: Shipping the Document Engine console rewriteA quarter-long console rewrite, 3,400 lines deleted, bundle nearly halved. What I kept, what I tossed, what I would do differently.

