All posts
EngineeringMarch 2, 2026·7 min read

How We Choose a Tech Stack for Every New Project

The question we get asked constantly

"Should we use Next.js or Remix?" "Should we go with PostgreSQL or MongoDB?" "What about Bun vs Node?"

These are the wrong questions, and the fact that they're so common reflects a real problem in how developers think about stack selection. The question isn't which technology is better in the abstract. The question is which technology is right for this project, this team, and this timeline.

Here's the framework we've developed after building across enough stacks to have strong opinions.

Constraint 1: Team fluency

The highest-leverage technology is the one your team already knows well.

A React team building in Svelte isn't moving faster because Svelte benchmarks better. They're moving slower because they're learning while shipping. That tax is almost never worth it unless the project has a specific requirement that justifies it.

We use Next.js for almost everything because our team knows it deeply. That fluency compounds — we've solved the edge cases, we know the failure modes, we have the tooling. That's worth more than switching to whatever framework posted impressive numbers last month.

Constraint 2: The scaling profile

Most projects don't have a scaling problem. Optimising for scale you won't hit for two years is premature architecture.

That said, some decisions are genuinely hard to reverse. Choosing a relational vs. document database matters more at 1M records than at 1K, and migrating is painful. Choosing a monolith vs microservices matters more at 50 engineers than at 5.

Our approach: default to boring, proven choices. Choose the architecture that fits the next 12–18 months, with clear seams at the places most likely to need to change. Don't build for 10x the scale you have. Do build for 2x.

Constraint 3: The deployment target

Where the software needs to run shapes the stack more than most teams admit.

Serverless (Vercel, Lambda) changes how you think about long-running processes and cold starts.
Mobile requires a different mental model for state management and offline behaviour. Enterprise clients often have compliance requirements that constrain your cloud provider choice.

We establish the deployment target before anything else. It eliminates a lot of debate.

What we default to and why

For web applications: Next.js (App Router), TypeScript, Tailwind, PostgreSQL (via Prisma or direct), deployed on Vercel or Railway.

This is a boring stack. It's boring because it works, it has excellent documentation, it has a huge hiring pool, and we've shipped dozens of applications on it without surprises.

For automation: n8n (self-hosted where possible), Postgres for state, webhooks for triggers.

For AI integrations: LangChain when we need the abstractions, raw SDK calls when we don't. We default to raw SDK calls more often than not.

The one rule we never break

Never choose a technology because it's interesting.

Interesting technologies are for side projects. Production systems should be boring. The most important quality of a production stack is that, six months from now, you can find the bug, fix it, and ship the fix without a week of archaeology.

If you want to learn Rust, build something on the weekend. If a client is paying you to ship, use the stack that gives them the most reliable outcome.

A note on switching costs

Stack debates consume enormous amounts of engineering time and almost never change the outcome.
The difference between a well-built product on a "worse" stack and a poorly-built product on an "optimal" stack is enormous. The difference between two well-built products on different reasonable stacks is negligible.

Pick something sensible. Go deep on it. Ship.

Ready to build something?

Tell us about your project and we'll get back to you within 24 hours.

New postsTwice monthly
TopicsEngineering · Product · AI
Written byThe Cherry Tech team