Every time I start a new project, the first few hours used to go to the same question: what should I build this with? I'd look at what's popular, read comparison posts, try a new framework. Then I'd spend more time configuring than building.
At some point I stopped doing that. I settled on a default stack. It's not perfect. It removes the decision and lets me start working, which matters more. If a project has unusual requirements, I'll adjust. But the default covers most of what I build.
Here's what I use and why.
The core idea
My stack is built around one principle: everything should live in the codebase, where AI can read it and act on it.
I use Claude Code for most of my development. When the backend logic, schema, server functions, and infrastructure config all live as files in the repo, the AI can see the full picture. It writes better code because it has better context. That's the thread connecting every choice below.
Backend: Convex
Convex is the centre of the stack. Schema, queries, mutations, background jobs and cron tasks are all TypeScript, all inside a /convex folder in the repo.
This matters because Claude Code can read those files directly. It sees the tables, the indexes, the functions, and how the frontend calls them. There's no separate database to connect to, no ORM to configure, no migration files to track. You write a function, it runs. You change the schema, the types update.
The reactive model is the other reason. Every query is a live subscription by default. The UI updates the moment the database changes. I don't think about WebSockets or polling or cache invalidation. For products where things change constantly, that removes a category of work I used to do by hand.
Convex also has a growing components ecosystem: auth, payments, rate limiting, email, background jobs, all modular packages you install and mount. The site you're reading uses the Better Auth component for its admin login. That was a few lines of code and a config entry.
The trade-off is that Convex uses a document model, not SQL. Complex analytical queries that would be a single JOIN in Postgres require more thought here. It's built for product backends, not data warehousing. For what I build, that's fine.
Frontend: TanStack Start
TanStack Start is a full-stack React framework built on TanStack Router and Vite.
The routing is type-safe end to end: params, loaders, and components. Server functions replace the need for a separate API layer, so you call them like normal async functions with full type inference. And it deploys anywhere: Netlify, Railway, Cloudflare, Node, Bun. You're not locked to a specific host.
AI models aren't as well-trained on TanStack Start as they are on Next.js, but in practice the difference isn't huge. TanStack Router has been around for a while, and Start builds on top of it, so models already understand the core patterns. You'll occasionally need to steer the AI with context, but it's not a blocker.
Hosting: Netlify + Railway
Netlify handles the frontend. Connect a repo, set a build command, done. It has a netlify.toml for configuration, which means the AI can manage redirects, headers, and env vars from code. TanStack Start is officially supported.
Railway handles anything that needs a persistent server: standalone APIs, databases, workers, background services. The DX is good. I can spin up a Postgres instance or a Bun server from a template in seconds, and everything lives in one dashboard.
Both have official MCP servers, @netlify/mcp and railwayapp/railway-mcp-server, so Claude Code can deploy, configure env vars, and manage infrastructure without leaving the terminal.
Netlify for frontends, Railway for services. Simple split for now.
Auth: depends on the project
I use Clerk when auth isn't a differentiator and I need to move fast. Pre-built sign-in components, social OAuth, MFA, organisations, all out of the box. The Convex integration is first-party. You pay for the convenience, and when speed matters that's a trade I'll make.
For projects where I want more control or data ownership, I use Better Auth. It's open-source, self-hosted, and has a good plugin system. More setup, but you own everything. Its Convex component is the most downloaded of any auth option in the ecosystem, which is part of why I trust it.
This site uses Better Auth. There's no universal answer.
AI tools
Claude Code handles most of my coding. It's the best I've used for agentic, multi-file work. It holds a whole codebase in view and makes coherent changes across many files at once. I pair it with the Convex, Netlify, and Railway MCP servers so it can manage the full stack.
The main thing I've learned: be explicit. Claude Code will expand scope if you let it. Telling it "only change this file" or "don't refactor anything else" keeps it focused. Worth the effort.
I use Codex as a second pair of eyes. It's noticeably good at catching edge cases and subtle bugs that Claude misses. When I'm stuck on something or want a different perspective on a problem, I'll run the same question through Codex. The two tools are complementary, not interchangeable.
For frontend design I use a combination of Claude Code and Gemini. Open source models like Kimi are making progress here too.
On paying for tools
If a paid tool lets me ship faster without reducing code quality or security, it's worth paying for. I optimise for the least friction between having an idea and having it live.
Clerk, Railway and Claude Code all cost money. The time they save is worth more than the subscription fees when you're building solo.
The full picture
| Layer | Tool |
|---|---|
| Backend | Convex |
| Frontend | TanStack Start |
| Hosting (frontend) | Netlify |
| Hosting (services) | Railway |
| Auth | Clerk or Better Auth |
| AI (coding) | Claude Code |
| AI (debugging) | Codex |
| AI (design) | Claude Code + Gemini |
Nothing here is bleeding-edge on its own. Everything lives in code, everything is readable by AI, and there's almost no configuration outside the repo.
I'll go deeper on individual choices in future posts.
