How we choose a stack — boring on purpose
Every week, some version of the same question: React or the newer thing? Postgres or the vector-native database? Which agent framework — surely not plain API calls?
It's always asked like a bet on the future. Pick right and win; pick wrong and rewrite. That frame is the mistake. A stack isn't a prediction — it's a liability schedule. Every technology you choose is something you will operate, debug mid-incident, hire for, defend in a security review, and eventually migrate away from. So the question isn't "which of these wins the next five years?" It's "what does this product need to survive the next two?"
Four rules
1. Proven under someone else's load. Choose technology whose failure modes are already documented — hit, named, and written up by teams that got there before you. That's what "boring" actually buys: not comfort, but a map of the sharp edges. Novel infrastructure means discovering the edges yourself, in production, on your users.
2. Chosen for the team you'll hire, not the demo you're giving. A stack is a hiring decision wearing a technical costume. Mainstream tools mean senior people who already know them exist, and answers to hard problems are a search away. The clever niche choice works fine — until the one person who understood it leaves.
3. Judged by how it fails, not how it demos. Everything demos well; that's what demos are for. The questions that matter arrive later. What do the logs look like when it breaks? Can you tell why it's slow, not just that it is? Does it degrade, or does it disappear? A technology you can't observe is a technology you can't operate.
4. Cheap to leave. Every choice ends someday. Standard interfaces, data you can export, seams between parts — these decide whether ending it is a project or a catastrophe. Your data will outlive every framework decision you make, which is why the database is the one place we are most conservative.
The innovation budget
You get a small number of novelty tokens per product. Spend them where your differentiation lives — for most AI-era products, that's the AI layer and your own domain — and nowhere else. A fashionable database under a CRUD workload is a token spent on risk with no return. The boring choice everywhere else is what makes the interesting choice affordable where it counts.
Our defaults
We re-choose per product; defaults are where the conversation starts, not a rule against leaving. Ours, named — this is the stack our own website and internal products run on:
- TypeScript, end to end. One language across the whole boundary. Types are cheap documentation for humans and machines alike.
- Next.js on the web front. Mature, well-trodden, hard to outgrow.
- Postgres by default. Relational until proven otherwise; JSON columns buy flexibility without a second database, and vector workloads usually start as an extension, not another store.
- A typed API service when the product earns one. Our internal products run a separate NestJS API where the domain warrants it — and a single Next.js app where it doesn't. The split is a decision, not a reflex.
- Managed platform first. Vercel-class hosting until scale or compliance writes a different bill. Undifferentiated infrastructure is not where a young product should spend attention.
- Migrations from day one. The schema is designed, versioned, and reviewed — never whatever the code happened to write last.
- The model behind a seam. Provider SDKs wrapped in your own interface, with evals, budgets, and a fallback decided when the feature is built — not after its first incident.
The AI-era reason boring got stronger
Two things changed stack economics recently, and both favor boring.
First: models write mainstream code better. Generation quality follows training mass, so the well-trodden stack gets you better AI-assisted velocity than the exotic one. An unusual stack now costs you twice — a thinner ecosystem and worse generation. Context is infrastructure, and mainstream stacks come with the context pre-built.
Second: the AI layer is the one place you can't be boring, because none of it is settled — models change under you, providers have bad days, prices move. So contain it. Keep the nondeterministic part behind an interface you own, measured by evals you wrote, with a budget someone watches. Rule four, applied where it pays most.
What we say no to
- Resume-driven architecture. The technology audition happens on someone else's product, not yours.
- Microservices before there's a service worth splitting. Distribution is a cost you pay when a boundary earns it.
- A new database per feature. Every store you add is an operational surface you now own.
- Mid-build fashion rewrites. Replacing a working boring thing with a fashionable one is prototype thinking in production clothes.
The short conversation
On first calls, the stack question is usually the short one. A good stack is one you get to stop thinking about — it holds, quietly, while you argue about the things that actually differentiate your product. If the stack conversation is the long one, something upstream is undecided.
Stack decisions live inside Build — strategy and architecture made with the business model in the room. Deciding now, or regretting a decision made at prototype speed? Talk to us.