Make decisions reversible
A lot of architecture advice assumes you can see the future. You can't, and neither can I. So instead of trying to make the right decision every time, I try to make reversible ones — decisions that are cheap to undo when, inevitably, I learn I was wrong.
You will be wrong
The database you pick, the boundary you draw, the library you bet on — some of these will turn out to be mistakes. That's not pessimism, it's just how building under uncertainty works. The question isn't whether you'll make wrong calls. It's how much each wrong call will cost to fix.
One-way doors and two-way doors
I borrow a simple frame: some decisions are two-way doors — you can walk back through if you don't like what's on the other side. Others are one-way doors that are painful or impossible to reverse. Spend your caution, your meetings, and your careful thinking on the one-way doors. For everything else, decide quickly and keep moving; the cost of being wrong is just walking back through.
Designing for reversal
Reversibility isn't luck — you build it in. Boundaries let you swap one side without disturbing the other. Adapters keep a vendor at arm's length. Keeping the domain free of framework details means you can change the framework later without a rewrite. Each of these turns a one-way door into a two-way one.
The goal isn't to predict correctly. It's to make being wrong cheap. A system full of two-way doors is a system you can keep changing as you learn — which, over a long enough project, is the only thing that actually matters.
Related notes
Tests as living contracts
A good test suite isn't a safety net you tolerate — it's the executable specification of what your system promises, including the properties that must always hold.
Boundaries before features
Why I draw the lines between modules before writing a single feature — and how it keeps a codebase from rotting as it grows.