Project Structure
Understanding the file layout of a generated better-ts-stack project
Overview
The exact layout of a generated project depends on the options you select. This page shows the realistic structures for common combinations.
Backend API - Express
Base (no optional modules)
The base Express template generates only src/index.ts and
src/routes/health.ts. No app.ts, routes/index.ts,
middleware/errorHandler.ts, types/, or README.md are created.
With PostgreSQL + Prisma + JWT Auth + Docker
With MongoDB + Mongoose + JWT Auth
Full-stack - Next.js
A full-stack project is a single Next.js application at the project root. There is no separate backend/ or frontend/ directory.
Base (no optional modules)
With PostgreSQL + Prisma + Better Auth + Docker
With PostgreSQL + Drizzle + Better Auth
Full-stack - TanStack Start
A TanStack Start project is a single Vite-based application at the project root. File-based routing lives in src/routes/. The CLI includes an initial src/routeTree.gen.ts, and TanStack Router regenerates it during Vite development and builds.
Base (no optional modules)
With PostgreSQL + Prisma + Better Auth + Docker
Key File Descriptions
Backend
| File | Purpose |
|---|---|
src/index.ts | Entry point - configures Express, mounts routes, starts the server |
src/routes/health.ts | GET /health endpoint |
src/lib/prisma.ts | Prisma client singleton |
src/lib/db.ts | Mongoose connection helper |
src/lib/jwt.ts | JWT sign/verify utilities |
src/middleware/requireAuth.ts | Bearer token validation middleware |
src/services/userStore.ts | In-memory or DB-backed user lookup for auth |
src/controllers/authController.ts | Register/login request handlers |
src/routes/auth.ts | Auth router mounted at /auth |
prisma/schema.prisma | Prisma schema - edit to add your models |
Full-stack (Next.js)
| File | Purpose |
|---|---|
app/layout.tsx | Root layout with font and metadata |
app/page.tsx | Home page |
app/globals.css | Tailwind CSS v4 import + design tokens |
proxy.ts | Dev proxy configuration (rendered from template) |
next.config.ts | Next.js configuration |
postcss.config.mjs | PostCSS setup for Tailwind |
components.json | shadcn CLI-compatible component metadata |
lib/utils.ts | Shared cn() helper for UI components |
lib/auth.ts | Better Auth server configuration |
lib/auth-client.ts | createAuthClient() for client components |
lib/auth-schema.ts | Shared auth form validation and error parsing |
lib/prisma.ts | Prisma client with @prisma/adapter-pg |
lib/db.ts | Drizzle database connection |
lib/schema.ts | Drizzle table definitions |
prisma.config.ts | Prisma datasource URL configuration |
drizzle.config.ts | Drizzle Kit configuration |
Full-stack (TanStack Start)
| File | Purpose |
|---|---|
src/routes/__root.tsx | Root route with layout, CSS, and devtools |
src/routes/index.tsx | Home page |
src/routeTree.gen.ts | Generated route tree (regenerated by Vite dev/build) |
src/routes/api/auth/$.ts | Better Auth route handler (auth.handler(request)) |
src/routes/sign-in.tsx | Login route with beforeLoad session guard |
src/routes/sign-up.tsx | Signup route with beforeLoad session guard |
src/routes/dashboard.tsx | Protected route example |
src/router.tsx | createRouter() + QueryClient + SSR query integration |
src/lib/auth.ts | Better Auth server configuration |
src/lib/auth-client.ts | createAuthClient() for client components |
src/lib/auth-functions.ts | getSession() server function |
src/lib/auth-schema.ts | Shared auth form validation and error parsing |
src/lib/prisma.ts | Prisma client with @prisma/adapter-pg |
src/lib/db.ts | Drizzle database connection |
src/lib/schema.ts | Drizzle table definitions |
src/components/ui/* | shadcn-style UI primitives (~/* imports) |
vite.config.ts | tanstackStart() + tailwind + react plugins |
components.json | shadcn CLI-compatible component metadata (~/*) |
prisma.config.ts | Prisma datasource URL configuration |
drizzle.config.ts | Drizzle Kit configuration |
Environment Variables
Variables are written to .env.example (and .env) based on selected modules.
Backend - base
NODE_ENV=development
PORT=3000+ PostgreSQL (Prisma or Drizzle)
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"+ MongoDB (Mongoose)
MONGODB_URI="mongodb://localhost:27017/myapp"+ JWT Auth (Express)
JWT_SECRET=please-change-me
JWT_EXPIRES_IN=1h+ Better Auth (Next.js / TanStack Start)
BETTER_AUTH_SECRET=please-change-me-to-a-random-string
BETTER_AUTH_URL=http://localhost:3000Always copy .env.example to .env and replace placeholder values before
starting the server. Never commit .env to git.