Every project is different. A real-time chat app has different needs than an e-commerce platform. A dashboard has different needs than a REST API. The stack should match the problem, not the other way around.
Here's how I think about it.
Start with the constraints
Before thinking about frameworks, I think about constraints. What are the hard requirements? Real-time updates? Heavy computation? High traffic? A specific deployment target? An existing team that needs to maintain this?
Constraints narrow the field fast. If you need real-time, you're probably looking at WebSockets and something like Node.js or Go. If you need heavy data processing, Python is a strong choice. If the team knows React, don't pick Vue just because you prefer it.
Optimize for the team
The best stack is one the team can actually use. A technically superior choice that nobody knows how to maintain is a bad choice. I'd rather use a "boring" technology that the team is productive with than a cutting-edge one that creates a bus factor of one.
This applies to solo projects too. If I'm handing off to a client, I pick tools they can hire for. React has a bigger talent pool than Svelte. PostgreSQL has better community support than CockroachDB. Sometimes boring is better.
My default stack
When there are no strong constraints pushing me in a specific direction, here's what I reach for:
- Frontend: React or Next.js with Tailwind CSS. Huge ecosystem, great DX, easy to hire for.
- Backend: Node.js with Express, or Python with FastAPI. Depends on whether it's I/O-heavy or compute-heavy.
- Database: PostgreSQL for relational data. MongoDB if the schema is genuinely flexible. Redis for caching and sessions.
- Deployment: VPS with nginx, Docker when it adds value, GitHub Actions for CI/CD.
This isn't a universal answer. It's a starting point that I deviate from when the problem calls for it.
When to go off-script
Sometimes the default isn't enough. A few examples:
Need server-sent events or long-lived connections? Node.js handles that naturally. Need to crunch numbers or do ML inference? Python with FastAPI. Building a CLI tool? Go. Need a quick prototype? A simple HTML/CSS/JS site with no build step.
The point isn't to have one answer — it's to have a decision framework that gets you to the right answer fast.
The anti-pattern
The biggest mistake I see is picking a stack based on what's trendy on Twitter. New doesn't mean better. Every technology has trade-offs. The cool new framework might have great DX but terrible documentation, a small community, and breaking changes every month.
Pick tools that solve your problem, have good support, and will still be around in 3 years. Save the experiments for side projects.