Our stack and why we chose it
Choosing a tech stack is one of the most consequential decisions a small team makes. Get it right, and you multiply your velocity for years. Get it wrong, and you spend more time fighting your tools than building your product. Here's every major technology choice we made at Steddi Labs, and the reasoning behind each one.
Next.js — the web foundation
Next.js is our framework for every web application. The App Router, server components, and built-in optimizations (image, font, script) mean we spend zero time on infrastructure and all our time on product. Vercel's deployment pipeline makes push-to-deploy effortless. Turbopack has made the dev server fast enough that we genuinely never wait for it.
We considered Remix, Astro, and even plain Vite + React. Next.js won because of the ecosystem maturity and the fact that our entire team already knows it deeply. Switching costs matter when you're small.
React Native + Expo — mobile without compromise
For mobile, we use React Native with Expo. Not because cross-platform is easier — it's not always — but because code sharing between web and mobile is a genuine multiplier for a small team. Shared types, shared business logic, shared design tokens.
Expo's managed workflow handles the parts of mobile development we never want to think about: builds, signing, OTA updates, native module configuration. EAS Build means we never touch Xcode or Android Studio for production builds.
Convex — real-time backend
Convex is the most opinionated choice in our stack, and the one we're most enthusiastic about. It replaces our database, API layer, real-time subscriptions, and server functions with a single, coherent platform.
For a real-time application, performance isn't optional — it's the product. Convex's reactive queries mean the UI updates automatically when data changes. No WebSocket management, no polling, no cache invalidation. You write a query, and the UI stays in sync. It's the closest thing to magic we've found in backend development.
Clerk — authentication solved
Authentication is one of those things that seems simple until you actually build it. Email/password, OAuth, magic links, multi-factor, session management, organization switching — the surface area is enormous. Clerk handles all of it with excellent React components and hooks.
The integration with Next.js middleware is particularly good. Protected routes, role-based access, and organization-scoped data all work out of the box. We went from zero to full auth in about an hour.
TypeScript — everywhere
This one isn't even a choice anymore — it's a requirement. TypeScript across the entire stack (frontend, backend, shared libraries) means type errors are caught at compile time, refactors are safe, and the code is self-documenting. We use strict mode with no exceptions.
Tailwind CSS — utility-first styling
Tailwind v4 with the new CSS-first configuration is a significant improvement over v3. Design tokens live in CSS variables, the PostCSS plugin is faster, and the developer experience is noticeably smoother. Combined with shadcn/ui for component primitives, we can build polished UIs without writing custom CSS.
AWS — for what needs it
For services that don't fit neatly into Vercel or Convex — file storage, email delivery, specialized compute — we use AWS. S3 for assets, SES for transactional email, and Lambda for occasional background jobs. We keep our AWS surface area as small as possible and let the managed services handle the rest.
What we'd do differently
Honestly? Not much. The stack has held up remarkably well as our products have grown. If we were starting over tomorrow, the only change we'd consider is adopting Tailwind v4 from day one instead of migrating from v3 — the migration was painless but unnecessary if you start fresh.
The real lesson is that the best stack isn't the most technically impressive one. It's the one your team knows well, that lets you ship fast, and that doesn't fight you when you need to change direction. Ours does all three.