I get asked about my stack a lot, usually after someone looks at the FieldCraft source or the SquaredR site. So here it is — everything I reach for on every new project, and why.
Next.js
I have tried Remix, Astro, and plain Vite setups. I keep coming back to Next.js. The app router with server components is the best model I have found for building sites that need both static content and dynamic features.
The file-based routing is simple. The metadata API is clean. Server actions work well for forms. ISR handles the "mostly static but occasionally changes" use case without me thinking about cache invalidation.
Is it perfect? No. The docs can be confusing, the bundler has quirks, and some things that should be simple require you to dig into GitHub issues. But nothing else gives me the same productivity for the type of work I do.
TypeScript
Non-negotiable. I do not start projects in plain JavaScript anymore. The upfront cost of adding types is nothing compared to the debugging time they save. TypeScript catches entire categories of bugs before the code runs.
I keep my tsconfig strict. strict: true, noUncheckedIndexedAccess: true, no any unless I have a very good reason. Loose TypeScript is barely better than JavaScript.
Tailwind CSS
I use Tailwind, but not the way most people use it. I do not write long chains of utility classes in JSX. I define CSS custom properties as design tokens and use Tailwind's @apply sparingly, mostly in component stylesheets.
For my own design system I write plain CSS with var(--sq-*) tokens. Tailwind handles the reset, the responsive breakpoints, and the occasional utility class where writing a full CSS rule would be overkill.
The key insight: Tailwind is a great utility layer, not a great design system. Build your design system on CSS custom properties, use Tailwind for the mechanical parts.
Prisma
For anything with a database, Prisma. The schema file is the best way I have found to define a data model. Migrations work reliably. The generated client is fully typed.
I have used Drizzle and it is good too — lighter, closer to SQL. But Prisma's schema-first approach fits how I think. Define the shape, generate everything else.
shadcn/ui
Not a component library — a collection of components you copy into your project. That distinction matters. I can modify any component without fighting a library's API or waiting for a PR to merge.
I use it as a starting point for UI components in FieldCraft and across client projects. The Radix primitives underneath handle accessibility correctly, which is hard to get right from scratch.
pnpm
Faster than npm, stricter than yarn. The strict node_modules structure catches phantom dependency issues that would slip through with npm's flat hoisting. Workspaces work well for managing multiple packages.
Vercel
Deploys Next.js without configuration. Preview deployments on every PR. Edge functions when I need them. I have tried self-hosting Next.js and it is doable but not worth the maintenance overhead for my use case.
What I have dropped
- Redux — React context or Zustand covers everything I need. Redux is too much ceremony for the apps I build.
- Styled-components — CSS custom properties and plain CSS files do the same job without the runtime cost.
- Jest — Vitest is faster and has the same API. No reason to stay on Jest for new projects.
- Webpack — Turbopack in Next.js or Vite everywhere else. Webpack configs are something I do not miss writing.
The boring answer is that I do not chase new tools. I find things that work, learn them deeply, and stick with them until something genuinely better shows up. Most of my stack has been stable for over a year.