Nov 20, 20252 min read
My Stack
Here's the stack where I'm currently the most productive.
1. Framework: Tanstack Start/Next.js + React
I've been building with React since 2017, and it's still where I move fastest. I start every project with TypeScript from day one.
Modern AI models are also highly capable with React, making it a strong choice for AI-assisted development workflows.
2. Styling: Tailwind CSS + shadcn/ui
Creating flexible, accessible, and maintainable components is challenging. In practice, you either extend an existing component system or build your own.
I use shadcn/ui because it provides thoughtfully designed, customizable components built on top of accessible, unstyled primitives. It covers everything from foundational elements like buttons and inputs to more advanced pieces like icons, charts, and custom themes.
The components are styled with Tailwind CSS, which works especially well with AI-assisted coding. Since styles live close to the markup, it's easier for both humans and AI tools to understand, generate, and modify components.
3. Database: Postgres + Drizzle
Postgres is my default database choice. Drizzle provides a lightweight, type-safe way to interact with Postgres while keeping the developer experience close to TypeScript.
I use:
- Drizzle ORM for database queries
- Drizzle Studio for viewing and editing data
- Drizzle Kit for schema changes and migrations
The TypeScript-first approach makes the entire stack feel consistent.
4. AI (Cursor)
I use Cursor and coding agents regularly for:
- Editing and refactoring code
- Debugging issues
- Exploring new ideas
- Making larger codebase changes
5. Coding Patterns
My AGENTS.md file:
- Only create an abstraction if it's actually needed
- Prefer clear function/variable names over inline comments
- Avoid helper functions when a simple inline expression would suffice
- Use
knipto remove unused code if making large changes - The
ghCLI is installed, use it - Don't use emojis
React
- React Compiler is enabled, so avoid manually adding
useMemoanduseCallback. - Break large JSX trees into smaller, composable components.
- Keep related code colocated.
- Avoid
useEffectunless there is a clear need for it.
Tailwind CSS
- Mostly use built-in values, occasionally allow dynamic values, rarely globals
- Always use v4 + global CSS file format + shadcn/ui
Content
- Use MDX for content-driven pages.
- Prefer fetching data in React Server Components.
- Keep pages static when possible.
- Add
priorityto above-the-fold images. - Be mindful of serialized prop size for RSC -> child components
TypeScript
- Avoid unnecessary
try/catchblocks. - Avoid using
anytype casts.