The stack matters less than the disciplines around it. Here's what I reach for, and why.
To render.
I lean React for anything user-facing because the ecosystem is mature and the escape hatches are well-documented. Next.js when I need routing, SSR, or RSC. Plain Vite when I just want to ship. Tailwind for the speed of iteration. TypeScript is non-negotiable.
To compute.
Most APIs I build are stateless and concurrent. Node.js when the UI and server can share types. Python whenever I need to do anything with embeddings, notebooks, or agent libraries. FastAPI specifically for the typing ergonomics and async support.
To store.
I prefer to know what each datastore is good at and use the right one rather than bend Postgres into a graph or vector index. Postgres for relational data with row-level security. Supabase when I need it managed. Neo4j for code-graph traversals. Qdrant for high-volume vector search; pgvector when the volume is small. Redis for cache and queues. SQLite when the answer is “just put it in a file.”
To reason.
Anthropic Claude as the default; OpenAI as the fallback when I need a different perspective or cheaper embeddings. MCP for tool-calling because it's the cleanest contract I've found between agent and host. Hybrid RAG: graph plus vector plus lexical, fused with rank-rerank, never one channel alone.
To ship.
Containers for anything stateful; Vercel for anything stateless and fronted by Next.js. Git as the source of truth, GitHub for collaboration and CI.