Indie Developer Tech Stack (Next.js Edition)

TL;DR

Application Framework: Next.js + TypeScript

Next.js should be the center of the entire product.

Marketing pages, the authenticated app, server-side rendering, APIs, and form submissions all live in a single project. Don't split frontend and backend from day one, and don't maintain two deployment pipelines for the sake of architectural tidiness.

The Next.js App Router natively provides file-based routing, Server Components, Server Functions, and server-side rendering; TypeScript unifies the frontend, backend, and data models.1

The real advantage of this combination isn't a performance metric — it's reducing context switching. Especially now that AI-assisted development has become the norm, a unified language and strict typing make generated code easier to verify.

In the Stack Overflow 2025 survey, TypeScript usage was 43.6%, React 44.7%, and Next.js 20.8%; GitHub statistics show TypeScript became the language with the most monthly contributors in August 2025.23

UI: Tailwind CSS + shadcn/ui

Use Tailwind CSS and shadcn/ui consistently across the UI.

Tailwind CSS handles styling, while shadcn/ui provides buttons, forms, modals, menus, and data tables. The component source code lives directly in your project, so you can modify it however you like instead of fighting a closed component library.4

This combination is structurally stable and fully transparent, and it's especially well suited to AI-assisted development. Indie developers don't need to invent an original design system — they just need to ship a consistent, professional, usable product interface quickly.

Database: PostgreSQL

Use PostgreSQL consistently for the database layer, but don't bind to a specific hosting platform.

PostgreSQL can handle users, orders, subscriptions, permissions, content, full-text search, and AI vector retrieval. In the Stack Overflow 2025 survey, PostgreSQL usage reached 55.6%, making it the most widely used database environment in the survey.2

In the current Vercel ecosystem, the default choice is Neon: it provides managed PostgreSQL through a native Marketplace integration, with auto-scaling, scale-to-zero, and database branching. When needed, you can create a separate database branch for preview deployments so database changes are validated alongside the branch environment.5

Neon is just the default implementation for the current deployment environment — it shouldn't become part of the application architecture. Business code accesses data through a standard PostgreSQL connection and Drizzle, and the database schema is managed through migrations; if you later switch to another PostgreSQL hosting service, you don't need to rewrite the domain model. Database connection strings must only live on the server — never expose them to the browser.

Authentication: Better Auth

Use Better Auth consistently for authentication.

Better Auth is a TypeScript-first authentication and authorization framework with built-in email/password login, social login, and account and session management, extensible through plugins with two-factor verification, Passkeys, and organization permissions. It integrates directly with Next.js Route Handlers, keeping authentication logic and user data in your own app and database.6

All server-side permission checks must be based on verified sessions — never trust a user ID sent by the client. Sensitive operations should also re-validate session validity, and users should be able to view and revoke logins on other devices.

File Storage: Vercel Blob

Use Vercel Blob consistently for avatars, screenshots, videos, and user-uploaded documents.

Vercel Blob integrates directly with Vercel projects and supports both public and private storage. Public assets use public blobs distributed directly via CDN; contracts, invoices, and user documents use private blobs, with the file returned only after the session is verified in a Vercel Function.7

Files shouldn't be stuffed into PostgreSQL, and you don't need to maintain a separate cloud service for object storage. For indie products deployed on Vercel, Blob already covers most upload and distribution scenarios.

Data Access: Drizzle ORM

Use Drizzle ORM consistently for database access.

Drizzle is a very thin TypeScript data access layer: it keeps SQL's expressiveness while providing type safety, schema definitions, and migration management.8

Database schemas must be versioned through migration files. Don't hand-edit tables in production and then hope you'll always remember what you changed.9

Data Validation: Zod

All external data must be validated with Zod, including form input, API parameters, environment variables, webhooks, and AI model output.

TypeScript only checks at compile time; it can't guarantee that the data arriving at runtime matches the types. Zod fills that gap.10

In an era of AI-generated code, reliability can't rest on "looks fine." Type checking, runtime validation, and database constraints — all three layers are indispensable.

Payments: Stripe

Use Stripe consistently for payments and subscriptions.

Stripe has turned Checkout, subscriptions, refunds, billing, and the customer portal into a mature product suite. Indie developers shouldn't design their own payment state machine.11

What deserves serious attention is webhooks. Successful renewals, failed payments, and subscription cancellations must all be handled by signature-verified events updating local entitlements — don't rely on page redirects after payment completes.12

Before building payment pages, complete merchant review and verify real billing.

Email: Resend

Use Resend consistently for verification codes, welcome emails, payment notifications, and system alerts.

Resend can be called directly from Next.js and lets you write email templates in React, without maintaining a separate template language.13

Email sending must use idempotency keys to avoid duplicate notifications from retries.

Testing: Vitest + Playwright

Vitest covers business rules and server functions; Playwright covers real user flows.

Vitest natively supports TypeScript and is great for quickly testing data transformations, permission checks, and billing logic.14

Playwright runs in a real browser and verifies signup, login, payment, and core product functionality.15

I don't chase pretty coverage numbers, but four flows must have end-to-end tests:

  • A user can sign up
  • A user can log in
  • A user can pay
  • A user can complete the product's core task

Write fewer tests if you must, but never leave the billing path reliant on manual prayer.

Monitoring & Analytics: Sentry + PostHog

Sentry answers "what broke"; PostHog answers "why users left."

Production exceptions must automatically collect stack traces, versions, and request context — don't wait for users to send screenshots.16

Product analytics should focus on signups, activation, core feature usage, and paid conversion — not on page views.17

Technology keeps the product running; data tells you whether the product is worth continuing.

Deployment: Vercel

Deploy Next.js directly to Vercel.

After connecting the repository, every commit builds automatically, each branch gets its own preview URL, and the main branch goes to production.18

Vercel isn't necessarily the cheapest platform in theory, but it cuts time spent on deployment, previews, and rollbacks.

Project Structure: pnpm + Single Repository

Use pnpm consistently for package management, keeping all code in a single repository.19

No microservices early on, no Kubernetes, no split frontend/backend repositories, and no complex Monorepo infrastructure.

Organize the project by business modules, but ultimately build and deploy it as a single Next.js application. That's the architecture I think suits indie development best: a modular monolith.

Summary

For indie developers, portability isn't the issue most worth investing in early on — shipping fast is. Most projects stop because they fail to deliver, long before they ever need to migrate.

This stack doesn't chase the absolute best in every technology; it pursues a combination that's complete, mature, and low-maintenance enough that one person can run the full loop — from development, to deployment, to charging customers — as quickly as possible.

Indie development doesn't need an architecture built for a billion users. What it really needs is a stack one person can understand, one repository can contain, one day can deploy, and that starts generating revenue as soon as possible.

Footnotes

  1. Next.js App Router (opens in a new tab); TypeScript Documentation (opens in a new tab)

  2. Stack Overflow Developer Survey 2025: Methodology (opens in a new tab), Technology (opens in a new tab), and Work (opens in a new tab) 2

  3. GitHub Octoverse 2025 (opens in a new tab)

  4. Tailwind CSS with Next.js (opens in a new tab); shadcn/ui Documentation (opens in a new tab)

  5. Neon for Vercel (opens in a new tab) and Neon Serverless Driver (opens in a new tab)

  6. Better Auth Introduction (opens in a new tab), Next.js Integration (opens in a new tab), and Session Management (opens in a new tab)

  7. Vercel Blob (opens in a new tab) and Private Storage (opens in a new tab)

  8. Drizzle ORM (opens in a new tab)

  9. Drizzle Kit Migrations (opens in a new tab)

  10. Zod Documentation (opens in a new tab)

  11. Stripe Subscriptions (opens in a new tab)

  12. Stripe Subscription Webhooks (opens in a new tab)

  13. Resend with Next.js (opens in a new tab); Send Email API (opens in a new tab)

  14. Vitest Guide (opens in a new tab)

  15. Playwright Documentation (opens in a new tab)

  16. Sentry for Next.js (opens in a new tab)

  17. PostHog for Next.js (opens in a new tab)

  18. Vercel Deployments (opens in a new tab)

  19. pnpm Documentation (opens in a new tab)