# My Stack

The technologies I reach for and why. Opinionated takes on TypeScript, Next.js, Tailwind, hosting, ORMs, auth, and more.


My [/about](/about#my-stack) 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. One language, shared types from database to UI, fewer bugs reaching production.

And [TypeScript 7](https://devblogs.microsoft.com/typescript/typescript-native-port/) is being rewritten in Go, so it should only get better.

## Framework: Next.js, TanStack Start, Hono

[Next.js](https://nextjs.org/) 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](https://tanstack.com/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](https://hono.dev/) 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](https://github.com/tannerlinsley), [Dominik Dorfmeister](https://tkdodo.eu/), and [Jack Herrington](https://www.youtube.com/@jherr). 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](https://github.com/styled-system/styled-system/). But Tailwind won me over. The JIT compiler, the universality across frameworks, and for advanced component workflows, [CVA](https://cva.style/) (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](https://ui.shadcn.com/) 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](https://figma.com/) is that tool.

## Hosting: Vercel, Netlify, Railway

Most of what I ship is hosted on [Vercel](https://vercel.com/). 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](https://netlify.com/) 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](https://railway.com/) for anything that needs a persistent server: Discord bots, background workers, or orchestrating multiple interdependent services.

For databases: [Neon](https://neon.tech/) when I need Postgres, [Turso](https://turso.tech/) when I don’t. Turso is built on [libSQL](https://docs.turso.tech/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](https://www.prisma.io/) 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](https://orm.drizzle.team/) 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](https://www.better-auth.com/) is the best thing that happened to [Auth.js](https://authjs.dev/): better documentation, better features, and you own your users’ data. That last part is why I can’t bring myself to use managed solutions like [Clerk](https://clerk.com/) or [WorkOS](https://workos.com/) 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](https://zod.dev/) 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](https://tanstack.com/form) for forms. Used [React Hook Form](https://react-hook-form.com/) for years, moving on. TanStack Form is [controlled by design](https://tanstack.com/form/v1/docs/philosophy): 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](https://tanstack.com/query) for client-side data fetching. Caching, refetching, stale-while-revalidate. Once you’ve used it, you can’t go back.

[tRPC](https://trpc.io/) for type safety between client and server. No code generation, no schema files, just TypeScript. Calling an API feels like calling a function.

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](https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components) vulnerability (CVE-2025-55182, CVSS 10.0 RCE) didn’t help. The [follow-up](https://react.dev/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components) disclosures made it worse. They still reduce boilerplate, but I have yet to release a project in production that uses them.

## Email: Resend

[Resend](https://resend.com/). Build email templates in JSX with [React Email](https://react.email/) instead of wrestling with table-based HTML from 2003. They also treat [agents as first-class citizens](https://resend.com/agents) with an MCP server and inbound email handling. Does one thing, does it well.

## CMS: Payload

[Payload](https://payloadcms.com/). 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](https://linear.app/), but working solo, it’s sometimes a bit much. These days I keep my backlog on GitHub Issues or just in markdown files. All three work well with the [Ralph Wiggum loop](/ai).

## AI SDK

Haven’t had many occasions to use [AI SDK](https://ai-sdk.dev/) yet. The few times I did, it felt obvious. I’d like to try [TanStack AI](https://tanstack.com/ai) next (you guessed it).

## LLM tools: Claude Code

[Claude Code](https://www.claude.com/product/claude-code) is my primary tool, even more so since Anthropic [stood its ground](https://www.anthropic.com/news/statement-department-of-war) against the Pentagon’s demands to allow unrestricted military use of Claude, at the cost of being [blacklisted as a supply chain risk](https://www.anthropic.com/news/statement-comments-secretary-war). That took guts.

I know there’s a turf war between Opus 4.6 and Codex 5.3. But it’s like switching lanes in traffic: I’d rather stay where I am and pay attention to where the companies are heading. Anthropic is far from perfect; I resent that my Claude Max subscription no longer works with [OpenCode](https://opencode.ai/), seeing PRs named ["Anthropic legal requests"](https://github.com/anomalyco/opencode/commit/973715f3da1839ef2eba62d4140fe7441d539411) on the OpenCode repo, or watching the [](https://x.com/openclaw/status/2016058924403753024) OpenClaw opportunity [slip through their fingers](https://steipete.me/posts/2026/openclaw) out of pride. Non-exhaustive list. But it’s the only major LLM provider I trust enough to give my time, money, and data to.

I still use [Cursor](https://cursor.com/) sporadically. I have a lot of respect for the team and the product, and I like trying new features and non-Anthropic models from time to time. But I always end up gravitating back to a TUI.

More on my AI usage on the [/ai](/ai) page, and my tool setup on [/uses](/uses).

> This is a /stack page, not yet an established convention — but 🤷. [See all slash pages](/slashes).
