6 min read

My default full-stack setup for new projects

The tools I reach for every time I start something new, and why I stopped second-guessing the stack.

My default full-stack setup for new projects

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 — not because it's perfect, but because it removes the decision and lets me start working. 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 your backend logic, schema, server functions, and infrastructure config all live as files in your repo, the AI can see and understand 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. Your schema, queries, mutations, background jobs, cron tasks — all TypeScript, all inside a /convex folder in your repo.

This matters because Claude Code can read those files directly. It sees your tables, your indexes, your 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 — it just works. For products where things change constantly, that's a big deal.

Convex also has a growing components ecosystem. Auth, payments, rate limiting, email, background jobs — modular packages you install and mount. The site you're reading uses the Loops component for the newsletter. That was a few lines of code, not a weekend project.

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. It's currently in RC — feature-complete, heading toward 1.0.

I picked it for a few reasons. The routing is fully type-safe, from params to loaders to components. Server functions replace the need for a separate API layer — 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: spin up a Postgres instance or a Bun server from a template in seconds. Everything lives in one dashboard.

Both have official MCP servers, which means Claude Code can deploy, configure env vars, and manage infrastructure without leaving the terminal. That matters when you're moving fast.

I may move to Cloudflare Pages at some point — their edge runtime is faster than Netlify's Lambda-based functions, and TanStack Start supports both. I went with Netlify initially because setup is simpler and there's less config to manage. Cloudflare's performance edge might be worth the extra wiring as projects scale.

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 solid. You pay for the convenience, but when speed matters, it's worth it.

For projects where I want more control or data ownership, I use Better Auth. It's open-source, self-hosted, and has an excellent plugin system. More setup, but you own everything. The Convex component has the highest downloads in the auth category on the Convex ecosystem.

There's no universal answer. The project decides.

AI tools

Claude Code handles most of my coding. It's the best I've used for agentic, multi-file work — understanding a codebase, making changes across many files, reasoning through architecture decisions. 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. "Only change this file," "don't refactor anything else" — that kind of direction 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 — layout, styling, component iteration — I use Gemini through Windsurf. The large context window helps when you're feeding in a full design system alongside existing components. It's not my go-to for logic, but for visual work it's useful.

On paying for tools

If a paid tool lets me ship faster without reducing code quality or security, it's worth paying for. I don't optimise for the cheapest stack. I optimise for the least friction between having an idea and having it live.

Clerk costs money. Railway costs money. Claude Code costs money. The time I save is worth more than the subscription fees. When you're building solo, your hours are the most expensive part of the operation.

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) | Gemini via Windsurf |

Nothing here is bleeding-edge on its own. The value is in how the pieces fit together — everything in code, everything accessible to AI, minimal configuration outside the repo.

I'll go deeper on individual choices in future posts. For now, this is the starting point. If you're picking a stack and can't decide, pick one that lets you start building today. You can always change it later. You can't get back the time you spent deciding.

Thanks for reading. Subscribe for more practical insights on building with AI.

New posts, real insights, and the stuff in between. Straight to your inbox.

Unsubscribe anytime. I respect your inbox.