Toolchain Preferences
Default technology stack and tooling choices for new projects.
Package Management
pnpm (Default)
Why pnpm:
- Faster than npm/yarn
- Disk-efficient through content-addressable storage
- Strict by default (no phantom dependencies)
- Better monorepo support
Usage:
pnpm install
pnpm add <package>
pnpm dev
Version Management: asdf
Node.js version per project:
# .tool-versions
nodejs 22.15.0
Ensures consistent environments across projects and machines.
Core Stack
Framework: Next.js App Router + TypeScript
Why Next.js:
- Full-stack React framework
- Server components, streaming, React Server Components (RSC)
- Excellent developer experience, fast iteration
- Zero-config routing, API routes, server actions
Always TypeScript:
- Type safety from database to UI
- Better IDE support, refactoring confidence
- Catches errors at compile time
Backend: Convex
Why Convex:
- Real-time database as a service
- Type-safe from database to UI (auto-generated types)
- Reactive queries with automatic caching
- No API layer needed — direct function calls
- Built-in auth, file storage, scheduling
When to use:
- Real-time features (chat, collaboration, live updates)
- Rapid prototyping (skip API boilerplate)
- Type-safe full-stack (database → UI)
Alternative: tRPC + Prisma for non-real-time apps
Deployment: Vercel
Why Vercel:
- Zero-config Next.js deployment
- Edge functions, analytics, preview deployments
- Tight integration with Next.js features (middleware, ISR, etc.)
- Great DX (git push → deployed)
UI Stack
Styling: Tailwind CSS + shadcn/ui
Tailwind CSS:
- Utility-first CSS for fast iteration
- Consistent design system via
tailwind.config.ts
- No CSS file overhead, tree-shakeable
- Responsive, dark mode, arbitrary values
shadcn/ui:
- Copy-paste components (NOT a dependency)
- Full control over component code
- Built on Radix primitives
- Accessible by default
Alternative: Use Radix UI directly for full customization
State Management: Zustand
Why Zustand:
- Minimal boilerplate vs Redux
- Simple API, works with React patterns
- Good for client-side state (Convex handles server state)
When to use:
- Client-side UI state (modals, forms, preferences)
- Cross-component state without prop drilling
Alternative: React Context + hooks for simple cases
Data Handling: TanStack Query + TanStack Table
TanStack Query:
- Server state management (when NOT using Convex)
- Caching, refetching, optimistic updates
- Replaces Redux for server data
TanStack Table:
- Headless table logic (sorting, filtering, pagination)
- Works with any UI framework
- Fully customizable, accessible
Build Tools
Default Build Tool by Project Type
Next.js projects:
- Use Next.js built-in build (Turbopack or webpack)
- Zero config, optimized for framework
Standalone apps (React/Vue/Svelte):
- Vite: Fast, modern, great DX
- HMR, instant server start, optimized builds
Libraries:
- tsup: Simple TypeScript bundler
- unbuild: Clean, minimal builds
Testing
Vitest (Default)
Why Vitest:
- Fast, modern test runner
- Compatible with Jest API (easy migration)
- Great TypeScript support
- Watch mode, coverage, snapshots
When to use:
- Unit tests, integration tests
- Component testing (with @testing-library/react)
E2E Testing:
- Playwright for end-to-end tests
Quick Reference
New Project Setup
# Create Next.js app with TypeScript
npx create-next-app@latest --typescript --tailwind --app
# Use pnpm
pnpm install
# Add Convex
pnpm add convex
npx convex dev
# Add shadcn/ui
npx shadcn@latest init
npx shadcn@latest add button card
# Add Zustand (if needed)
pnpm add zustand
# Add testing
pnpm add -D vitest @testing-library/react @testing-library/jest-dom
Dependency Decision Tree
Need real-time data?
- YES → Convex
- NO → TanStack Query + API layer (or tRPC)
Need complex client state?
- YES → Zustand
- NO → React Context + useState/useReducer
Need data tables?
- YES → TanStack Table
- NO → Plain HTML table or simple list
Need UI components?
- Start with shadcn/ui (copy-paste)
- Customize as needed (you own the code)
When to Deviate
Valid Deviations
Static sites:
- Consider Astro instead of Next.js
- Better for content-heavy, low-interactivity sites
Non-real-time apps:
- tRPC + Prisma instead of Convex
- More control over database schema, migrations
Simple projects:
- React Context instead of Zustand
- Reduce dependencies for small apps
Component libraries:
- Radix UI directly instead of shadcn
- When you need 100% control from start
Anti-Patterns to Avoid
❌ npm/yarn — Use pnpm for consistency
❌ Redux — Too much boilerplate; use Zustand or TanStack Query
❌ Class components — Use function components + hooks
❌ CSS-in-JS (styled-components, Emotion) — Runtime overhead; use Tailwind
❌ Create React App — Deprecated; use Vite or Next.js
❌ Component libraries as dependencies — Prefer shadcn copy-paste approach
Philosophy
Opinionated defaults, pragmatic deviations.
These tools work well together, have been battle-tested, and provide excellent developer experience. But they're defaults, not dogma.
Choose tools that:
- Solve real problems (not resume-driven development)
- Have good documentation and community
- Integrate well with the rest of the stack
- Match project requirements (not all projects need real-time)
Prefer boring technology that works over shiny technology that might.
1---2name: toolchain-preferences-23description: Apply preferred toolchain and technology stack defaults: pnpm, Next.js, TypeScript, Convex, Vercel, Tailwind, shadcn/ui, Zustand, TanStack, Vitest. Use when setting up new projects, choosing dependencies, discussing stack decisions, or evaluating alternatives.4---56# Toolchain Preferences78Default technology stack and tooling choices for new projects.910## Package Management1112### pnpm (Default)1314**Why pnpm:**15- Faster than npm/yarn16- Disk-efficient through content-addressable storage17- Strict by default (no phantom dependencies)18- Better monorepo support1920**Usage:**21```bash22pnpm install23pnpm add <package>24pnpm dev25```2627### Version Management: asdf2829**Node.js version per project:**30```31# .tool-versions32nodejs 22.15.033```3435Ensures consistent environments across projects and machines.3637## Core Stack3839### Framework: Next.js App Router + TypeScript4041**Why Next.js:**42- Full-stack React framework43- Server components, streaming, React Server Components (RSC)44- Excellent developer experience, fast iteration45- Zero-config routing, API routes, server actions4647**Always TypeScript:**48- Type safety from database to UI49- Better IDE support, refactoring confidence50- Catches errors at compile time5152### Backend: Convex5354**Why Convex:**55- Real-time database as a service56- Type-safe from database to UI (auto-generated types)57- Reactive queries with automatic caching58- No API layer needed — direct function calls59- Built-in auth, file storage, scheduling6061**When to use:**62- Real-time features (chat, collaboration, live updates)63- Rapid prototyping (skip API boilerplate)64- Type-safe full-stack (database → UI)6566**Alternative:** tRPC + Prisma for non-real-time apps6768### Deployment: Vercel6970**Why Vercel:**71- Zero-config Next.js deployment72- Edge functions, analytics, preview deployments73- Tight integration with Next.js features (middleware, ISR, etc.)74- Great DX (git push → deployed)7576## UI Stack7778### Styling: Tailwind CSS + shadcn/ui7980**Tailwind CSS:**81- Utility-first CSS for fast iteration82- Consistent design system via `tailwind.config.ts`83- No CSS file overhead, tree-shakeable84- Responsive, dark mode, arbitrary values8586**shadcn/ui:**87- Copy-paste components (NOT a dependency)88- Full control over component code89- Built on Radix primitives90- Accessible by default9192**Alternative:** Use Radix UI directly for full customization9394### State Management: Zustand9596**Why Zustand:**97- Minimal boilerplate vs Redux98- Simple API, works with React patterns99- Good for client-side state (Convex handles server state)100101**When to use:**102- Client-side UI state (modals, forms, preferences)103- Cross-component state without prop drilling104105**Alternative:** React Context + hooks for simple cases106107### Data Handling: TanStack Query + TanStack Table108109**TanStack Query:**110- Server state management (when NOT using Convex)111- Caching, refetching, optimistic updates112- Replaces Redux for server data113114**TanStack Table:**115- Headless table logic (sorting, filtering, pagination)116- Works with any UI framework117- Fully customizable, accessible118119## Build Tools120121### Default Build Tool by Project Type122123**Next.js projects:**124- Use Next.js built-in build (Turbopack or webpack)125- Zero config, optimized for framework126127**Standalone apps (React/Vue/Svelte):**128- Vite: Fast, modern, great DX129- HMR, instant server start, optimized builds130131**Libraries:**132- tsup: Simple TypeScript bundler133- unbuild: Clean, minimal builds134135## Testing136137### Vitest (Default)138139**Why Vitest:**140- Fast, modern test runner141- Compatible with Jest API (easy migration)142- Great TypeScript support143- Watch mode, coverage, snapshots144145**When to use:**146- Unit tests, integration tests147- Component testing (with @testing-library/react)148149**E2E Testing:**150- Playwright for end-to-end tests151152## Quick Reference153154### New Project Setup155156```bash157# Create Next.js app with TypeScript158npx create-next-app@latest --typescript --tailwind --app159160# Use pnpm161pnpm install162163# Add Convex164pnpm add convex165npx convex dev166167# Add shadcn/ui168npx shadcn@latest init169npx shadcn@latest add button card170171# Add Zustand (if needed)172pnpm add zustand173174# Add testing175pnpm add -D vitest @testing-library/react @testing-library/jest-dom176```177178### Dependency Decision Tree179180**Need real-time data?**181- YES → Convex182- NO → TanStack Query + API layer (or tRPC)183184**Need complex client state?**185- YES → Zustand186- NO → React Context + useState/useReducer187188**Need data tables?**189- YES → TanStack Table190- NO → Plain HTML table or simple list191192**Need UI components?**193- Start with shadcn/ui (copy-paste)194- Customize as needed (you own the code)195196## When to Deviate197198### Valid Deviations199200**Static sites:**201- Consider Astro instead of Next.js202- Better for content-heavy, low-interactivity sites203204**Non-real-time apps:**205- tRPC + Prisma instead of Convex206- More control over database schema, migrations207208**Simple projects:**209- React Context instead of Zustand210- Reduce dependencies for small apps211212**Component libraries:**213- Radix UI directly instead of shadcn214- When you need 100% control from start215216### Anti-Patterns to Avoid217218❌ **npm/yarn** — Use pnpm for consistency219220❌ **Redux** — Too much boilerplate; use Zustand or TanStack Query221222❌ **Class components** — Use function components + hooks223224❌ **CSS-in-JS (styled-components, Emotion)** — Runtime overhead; use Tailwind225226❌ **Create React App** — Deprecated; use Vite or Next.js227228❌ **Component libraries as dependencies** — Prefer shadcn copy-paste approach229230## Philosophy231232**Opinionated defaults, pragmatic deviations.**233234These tools work well together, have been battle-tested, and provide excellent developer experience. But they're defaults, not dogma.235236Choose tools that:2371. Solve real problems (not resume-driven development)2382. Have good documentation and community2393. Integrate well with the rest of the stack2404. Match project requirements (not all projects need real-time)241242**Prefer boring technology that works over shiny technology that might.**