Better-TS-Stack

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)

index.ts
package.json
tsconfig.json
.env
.env.example
.eslintrc.js
eslint.config.mjs
.prettierrc
.gitignore

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

schema.prisma
index.ts
Dockerfile
docker-compose.yml
.dockerignore
package.json
tsconfig.json
.env
.env.example
.gitignore

With MongoDB + Mongoose + JWT Auth

index.ts
package.json
tsconfig.json
.env
.env.example
.gitignore

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)

layout.tsx
page.tsx
globals.css
components.json
proxy.ts
next.config.ts
postcss.config.mjs
tsconfig.json
eslint.config.mjs
next-env.d.ts
package.json
.env
.env.example
.gitignore

With PostgreSQL + Prisma + Better Auth + Docker

layout.tsx
page.tsx
globals.css
auth.ts
auth-client.ts
auth-schema.ts
prisma.ts
utils.ts
schema.prisma
proxy.ts
prisma.config.ts
next.config.ts
postcss.config.mjs
tsconfig.json
eslint.config.mjs
Dockerfile
docker-compose.yml
.dockerignore
package.json
.env
.env.example
.gitignore

With PostgreSQL + Drizzle + Better Auth

layout.tsx
page.tsx
globals.css
auth.ts
auth-client.ts
auth-schema.ts
db.ts
schema.ts
utils.ts
proxy.ts
drizzle.config.ts
next.config.ts
package.json
.env
.env.example
.gitignore

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)

routeTree.gen.ts
router.tsx
components.json
vite.config.ts
tsconfig.json
eslint.config.mjs
package.json
.env
.env.example
.gitignore

With PostgreSQL + Prisma + Better Auth + Docker

routeTree.gen.ts
router.tsx
components.json
vite.config.ts
prisma.config.ts
tsconfig.json
eslint.config.mjs
Dockerfile
docker-compose.yml
.dockerignore
package.json
.env
.env.example
.gitignore

Key File Descriptions

Backend

FilePurpose
src/index.tsEntry point - configures Express, mounts routes, starts the server
src/routes/health.tsGET /health endpoint
src/lib/prisma.tsPrisma client singleton
src/lib/db.tsMongoose connection helper
src/lib/jwt.tsJWT sign/verify utilities
src/middleware/requireAuth.tsBearer token validation middleware
src/services/userStore.tsIn-memory or DB-backed user lookup for auth
src/controllers/authController.tsRegister/login request handlers
src/routes/auth.tsAuth router mounted at /auth
prisma/schema.prismaPrisma schema - edit to add your models

Full-stack (Next.js)

FilePurpose
app/layout.tsxRoot layout with font and metadata
app/page.tsxHome page
app/globals.cssTailwind CSS v4 import + design tokens
proxy.tsDev proxy configuration (rendered from template)
next.config.tsNext.js configuration
postcss.config.mjsPostCSS setup for Tailwind
components.jsonshadcn CLI-compatible component metadata
lib/utils.tsShared cn() helper for UI components
lib/auth.tsBetter Auth server configuration
lib/auth-client.tscreateAuthClient() for client components
lib/auth-schema.tsShared auth form validation and error parsing
lib/prisma.tsPrisma client with @prisma/adapter-pg
lib/db.tsDrizzle database connection
lib/schema.tsDrizzle table definitions
prisma.config.tsPrisma datasource URL configuration
drizzle.config.tsDrizzle Kit configuration

Full-stack (TanStack Start)

FilePurpose
src/routes/__root.tsxRoot route with layout, CSS, and devtools
src/routes/index.tsxHome page
src/routeTree.gen.tsGenerated route tree (regenerated by Vite dev/build)
src/routes/api/auth/$.tsBetter Auth route handler (auth.handler(request))
src/routes/sign-in.tsxLogin route with beforeLoad session guard
src/routes/sign-up.tsxSignup route with beforeLoad session guard
src/routes/dashboard.tsxProtected route example
src/router.tsxcreateRouter() + QueryClient + SSR query integration
src/lib/auth.tsBetter Auth server configuration
src/lib/auth-client.tscreateAuthClient() for client components
src/lib/auth-functions.tsgetSession() server function
src/lib/auth-schema.tsShared auth form validation and error parsing
src/lib/prisma.tsPrisma client with @prisma/adapter-pg
src/lib/db.tsDrizzle database connection
src/lib/schema.tsDrizzle table definitions
src/components/ui/*shadcn-style UI primitives (~/* imports)
vite.config.tstanstackStart() + tailwind + react plugins
components.jsonshadcn CLI-compatible component metadata (~/*)
prisma.config.tsPrisma datasource URL configuration
drizzle.config.tsDrizzle 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:3000

Always copy .env.example to .env and replace placeholder values before starting the server. Never commit .env to git.

On this page