Configuration
Environment variables, package.json, and TypeScript configuration
Configuration Overview
This page lists the configuration files a generated project contains and the environment variables you need to set.
Environment Variables
Backend (.env)
The CLI writes these variables to .env and .env.example, depending on the modules you selected:
# Base (always generated). NODE_ENV is set by the dev and start scripts.
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=1hFull-stack / Next.js (.env)
# TanStack Start only. Next.js picks its port before it loads .env.
# NODE_ENV is set by next, vite, and the Nitro server.
PORT=3000
# + Better Auth (requires database)
BETTER_AUTH_SECRET=please-change-me-to-a-random-string
BETTER_AUTH_URL=http://localhost:3000.env.example keeps the placeholder values shown here. In .env, the CLI
replaces JWT_SECRET and BETTER_AUTH_SECRET with a random 64-character
value, so each project gets its own secret.
Environment-Specific Files
You can create separate files for different environments:
.env.development- Development-specific.env.production- Production-specific.env.test- Testing environment
Never commit .env files to version control! Use .env.example as a
template.
TypeScript Configuration
Backend tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": ["node"],
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Frontend tsconfig.json
The Next.js template ships with this tsconfig.json:
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}Package.json Scripts
Backend (Express) scripts
These are generated by the Express base module:
{
"scripts": {
"dev": "cross-env NODE_ENV=development tsx watch src/index.ts",
"build": "tsc",
"start": "cross-env NODE_ENV=production node dist/index.js",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"format": "prettier --write \"src/**/*.ts\"",
"type:check": "tsc --noEmit"
}
}With bun,
devrunsbun --watch src/index.tsandstartrunsbun dist/index.js, still throughcross-env.
Prisma module adds: prisma:generate, prisma:migrate, prisma:studio
Docker module adds: docker:build, docker:up, docker:down, docker:logs
Full-stack (Next.js) scripts
These are generated by the Next.js base module:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
}
}Prisma module adds: prisma:generate, prisma:migrate, prisma:studio
Drizzle module adds: db:generate, db:migrate, db:studio
Docker module adds: docker:build, docker:up, docker:down, docker:logs
ESLint Configuration
Backend eslint.config.mjs
ESLint 10 reads the flat config in eslint.config.mjs. The Express template uses typescript-eslint with type-aware rules. A shortened version:
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ["dist", "node_modules", "src/generated/**"] },
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
project: "./tsconfig.eslint.json",
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
"@typescript-eslint/no-floating-promises": "error",
"no-console": "off",
},
}
);Prettier Configuration
.prettierrc
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"arrowParens": "always"
}Docker Configuration
Multi-Stage Dockerfile
See full Dockerfile in Docker Module.
docker-compose.yml
The generated file defines an app service, and a db service when you choose a database:
services:
app:
build: .
ports:
- "3000:3000"
env_file:
- .env
environment:
- NODE_ENV=production
restart: unless-stoppedWith a database, Compose also runs PostgreSQL or MongoDB and the app waits until it is healthy. See the Docker module docs.
Prisma Configuration
schema.prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
moduleFormat = "cjs"
}
datasource db {
provider = "postgresql"
}
model User {
id String @id @default(uuid())
email String @unique
name String?
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("users")
}In Next.js projects, the datasource URL is loaded via prisma.config.ts. If
Better Auth is enabled, the generated Prisma schema includes Better Auth
tables (user, session, account, verification).
prisma.config.ts (Next.js)
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
// prisma generate needs no URL, so a build without .env (CI, a host) works.
// Commands that connect report the empty URL
url: process.env.DATABASE_URL ?? "",
},
});prisma/migrations
Run migrations:
# Create migration
npx prisma migrate dev --name add_user_table
# Apply migrations
npx prisma migrate deploy
# Reset database (careful!)
npx prisma migrate resetNext.js Configuration
next.config.ts
Without Docker, the generated file is empty apart from the type import:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {};
export default nextConfig;If you choose Docker, it also sets output: "standalone", which the Docker image runs with node server.js.
Add options as you need them. See the Next.js configuration docs for available options.
Custom Configuration
Adding Custom Scripts
Edit package.json:
{
"scripts": {
"db:seed": "tsx prisma/seed.ts",
"db:reset": "prisma migrate reset --force",
"docker:build": "docker build -t myapp .",
"docker:run": "docker run -p 3000:3000 myapp"
}
}Custom TypeScript Paths
Add to tsconfig.json:
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"]
}
}
}You can edit any of these configuration files after generation.