A Practical Guide to Choosing Your Fullstack Stack
Jun 22, 2024 · 8 min read
Every new project starts with the same question: what stack should I use? After building across Rails, Go, React Native, and various frontends, here's my current framework for choosing.
The Decision Tree
You make these decisions in order. Each one constrains the next.
Database
Start with Postgres. The only reason to pick something else is if you have a specific constraint that rules it out — extreme write throughput (go Cassandra), document model (go Mongo), or local-first sync (go ElectricSQL/SQLite).
Postgres with pgvector handles vector search, JSONB handles flexible schemas, and logical replication powers real-time sync. One database, most problems solved.
API Layer
Three tiers:
- Rails — fastest to ship, excellent for CRUD-heavy apps, great ecosystem
- Go — best for high-concurrency APIs, microservices, resource-constrained environments
- Elysia.js (Bun) — modern, fast, good for JS/TS teams that want performance without leaving the ecosystem
Pick the one your team knows best. The API layer is the easiest to change later.
Auth
Don't build auth yourself. Supabase Auth, Clerk, or Auth0 handle the hard parts — password hashing, session management, OAuth providers, rate limiting. The cost is negligible compared to the security surface area you'd need to maintain.
Client
- Remix — best for content-heavy, SEO-required sites
- React Native — when you need mobile
- Plain server-rendered templates — underrated for internal tools and simple CRUD
Styling
Tailwind CSS. Every time. The purge step means zero unused CSS in production, and the utility class system eliminates context-switching between HTML and stylesheets.
Hosting
- Vercel — best DX for frontend-heavy apps
- Fly.io — good for stateful backends near the edge
- Single VPS (Hetzner/DigitalOcean) — cheapest for monolithic apps under moderate load
The Rule
Don't optimize for scale you don't have.
Pick the stack that lets you ship the first version fastest. You'll know when to change when the pain of the current stack exceeds the cost of migration.