Resume
HomeAbout/Contact
← Writing

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 knip to remove unused code if making large changes
  • The gh CLI is installed, use it
  • Don't use emojis

React

  • React Compiler is enabled, so avoid manually adding useMemo and useCallback.
  • Break large JSX trees into smaller, composable components.
  • Keep related code colocated.
  • Avoid useEffect unless 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 priority to above-the-fold images.
  • Be mindful of serialized prop size for RSC -> child components

TypeScript

  • Avoid unnecessary try/catch blocks.
  • Avoid using any type casts.