My Stack
My /about page lists what I use. This page explains why. I value simplicity, small surface areas, and tools that let me ship without fighting the framework. I’d rather use boring technology that works than chase the new thing every quarter.
Language: TypeScript
TypeScript everywhere: front-end, back-end, scripts, tooling. Sharing types from the database down to the UI catches a whole class of bugs before they ship.
And TypeScript 7, the Go-native port of the compiler, just shipped: same type-checking semantics, builds roughly 10× faster.
Framework: Next.js, TanStack Start, Hono
Next.js has been my default for years. The App Router, server components, and the Vercel ecosystem make it hard to beat for content-heavy sites and SaaS products. This site runs on it.
For new projects that aren’t static, I’m leaning towards TanStack Start. Full-stack TypeScript without the opinions Next.js imposes. It’s newer, still rough around the edges, but the primitives are solid and the direction feels right.
Hono for APIs and lightweight services. Fast, runs everywhere (Cloudflare Workers, Bun, Node), and the middleware system is clean.
You’ll notice TanStack shows up a lot on this page (Start, Query, Form). There are very few people in the ecosystem I respect as much as Tanner Linsley, Dominik Dorfmeister, and Jack Herrington. The quality and consistency of what they put out, combined with how well they teach what they know, is rare.
Styling: Tailwind + shadcn/ui
I was a Styled-components person for a long time, and even co-created a library compatible with styled-system. But Tailwind won me over. The JIT compiler, the universality across frameworks, and for advanced component workflows, CVA (Class Variance Authority) make it hard to go back. The iteration speed is something else, and the constraint system keeps CSS from rotting over time.
shadcn/ui on top gives me accessible, well-built components that I own and can modify. No dependency to update, no breaking changes to track. Copy, paste, adapt.
Design: Figma
I’ve always had a tendency to design directly in CSS, and LLMs have only made that worse. Or better? But for anything that requires real craft (spacing, visual rhythm, fine-tuning details), it’s still easier to work in a proper design tool. Figma is that tool.
Hosting: Vercel, Netlify, Railway
Most of what I ship is hosted on Vercel. The DX is the best I’ve used for Next.js projects, and I’d be lying if I said otherwise. I’m not entirely comfortable, though, with some of the political positions taken and displayed by its leadership, whether through tweets or selfies. It’s not about vendor lock-in or Next.js bashing, it’s just a gut feeling that won’t go away.
Netlify holds a special place for me. Mathias Biilmann and his team championed the Jamstack, which was my workhorse for years. I haven’t deployed anything there in a while, but I’d like to find a reason to go back.
Railway for anything that needs a persistent server: Discord bots, background workers, or orchestrating multiple interdependent services.
For databases: Neon when I need Postgres, Turso when I don’t. Turso is built on libSQL, an open-source fork of SQLite with native replication across edge locations.
I’m cautious about recommending heavier infrastructure. I won’t suggest Kubernetes or Terraform until they’re actually needed. Most projects I’ve worked on would have shipped faster and cost less without them. The same goes for monorepos: the DX overhead used to be a dealbreaker, but LLMs are getting good at compensating for the complexity we can’t be bothered to master. The calculus is shifting.
ORM: Prisma, Drizzle
Prisma was my default for years. Solid migrations, good schema-first workflow. But heavy. The generated client is large and cold starts on serverless grind my gears.
Drizzle is where I’m heading. Closer to SQL, lighter, and if you’re starting something new today, just use Drizzle.
Auth: Better Auth
Auth is one of those things you should almost never build from scratch.
Better Auth is the best thing that happened to auth since Auth.js: better documentation, better features, and you still own your users’ data. That last part is why I can’t bring myself to use managed solutions like Clerk or WorkOS for SAML/SSO. I understand why people do, and the DX is good. But not owning my user table is a tradeoff I’m not willing to make.
Validation: Zod, TanStack Form
Zod everywhere. API inputs, environment variables, form validation. It plugs into everything I use (tRPC, TanStack Form, Payload) and the TypeScript inference just works. Not much else to say.
TanStack Form for forms. Used React Hook Form for years, moving on. TanStack Form is controlled by design: predictable state, works outside the DOM (React Native, Three.js), easier to test. RHF’s uncontrolled approach was clever, but controlled wins when you need to actually reason about what’s going on.
Data flow: tRPC, server actions
TanStack Query for client-side data fetching. It handles the caching, refetching, and stale-while-revalidate plumbing nobody should be writing by hand (apart from their contributors, mind you).
tRPC for type safety between client and server. Rename a field in a router and the front-end turns red immediately, with no codegen step or schema file to keep in sync.
Server actions for simpler mutations where tRPC would be overkill. I’m less confident about them than I used to be. The ecosystem doesn’t seem to be fully rallying behind them, and the React2Shell vulnerability (CVE-2025-55182, CVSS 10.0 RCE) didn’t help. The follow-up disclosures made it worse. They still reduce boilerplate, but I have yet to release a project in production that uses them.
Email: Resend
Resend. Build email templates in JSX with React Email instead of wrestling with table-based HTML from 2003. They also treat agents as first-class citizens with an MCP server and inbound email handling. Does one thing, does it well.
CMS: Payload
Payload. Code-first, runs on Next.js, admin panel generated from your config. Drizzle under the hood, Zod for validation. It just slots into everything else on this page.
Task management
I hate Jira with every fiber of my being. I love Linear with all my heart, but working solo, it’s sometimes a bit much. These days my backlog lives in beads, an issue tracker stored in git and built for coding agents. A natural fit for the Ralph Wiggum loop.
AI SDK
AI SDK feels obvious every time I use it. I’d have liked to try TanStack AI (you guessed it), but AI SDK 7 makes it harder to justify: durability, tool approvals, sandboxes… with zero vendor lock-in so far.
More on my AI usage on the /ai page, and my LLM tooling on /uses.
This is a /stack page, not yet an established convention — but 🤷. See all slash pages.