Project Templates
What files and code better-ts-stack actually generates
This page lists the files and scripts the CLI generates for each option.
Backend API Template (Express)
Selecting Backend API with Express generates:
The base template has three source files: src/index.ts, src/env.ts, and
src/routes/health.ts.
src/index.ts
The entry point configures Express middleware, mounts the health route, and starts the server:
import cors from "cors";
import "dotenv/config";
import express, { Express, NextFunction, Request, Response } from "express";
import helmet from "helmet";
import morgan from "morgan";
import healthRouter from "./routes/health";
const app: Express = express();
const port = process.env.PORT || 3000;
app.use(helmet());
app.use(cors());
app.use(morgan("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/health", healthRouter);
// 404 handler
app.use((_req: Request, res: Response) => {
res.status(404).json({ error: "Not Found" });
});
// Error handler
app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
console.error(err.stack);
res.status(500).json({ error: "Internal Server Error" });
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
console.log(`Health: http://localhost:${port}/health`);
});
export default app;Generated package.json scripts
{
"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 as the package manager,
devbecomesbun --watch src/index.ts.
Full-stack Templates
Selecting Full-stack generates one application at the project root, with no separate backend/ or frontend/ folders. You pick the framework in the next prompt.
Next.js
Generated package.json scripts
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
}
}TanStack Start
src/
|-- routes/ # File-based routes (__root.tsx, index.tsx)
|-- routeTree.gen.ts # Generated route tree
|-- router.tsx # createRouter() + QueryClient + SSR query integration
|-- lib/utils.ts # cn() helper
|-- components/ui/ # shadcn-compatible base UI primitives
|-- styles/app.css # Tailwind CSS v4 import + base styles
vite.config.ts # tanstackStart() + tailwind + react plugins
components.json # shadcn CLI-compatible component config
package.json # "type": "module"The template uses the ~/* path alias mapped to src/*. vite build runs the
Nitro plugin, which writes a self-contained Node.js server to .output/, and the
start script runs it with node, as TanStack's hosting guide recommends. The CLI includes the initial route tree, and TanStack Router
regenerates it during Vite development and builds.
Generated package.json scripts
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "node --env-file-if-exists=.env .output/server/index.mjs",
"preview": "vite preview",
"type:check": "tsc --noEmit",
"lint": "eslint src"
}
}With Database Modules
PostgreSQL + Prisma
Scripts added to package.json:
npm run prisma:generate
npm run prisma:migrate # prisma migrate dev
npm run prisma:studioEnvironment variable added: DATABASE_URL
PostgreSQL + Drizzle
For TanStack Start, the schema and client live in
src/lib/schema.tsandsrc/lib/db.ts(drizzle.config.tspoints at./src/lib/schema.ts).
Scripts added to package.json:
npm run db:generate # drizzle-kit generate
npm run db:migrate # drizzle-kit migrate
npm run db:studio # drizzle-kit studioEnvironment variable added: DATABASE_URL
If Better Auth is also enabled with Drizzle, the generated lib/schema.ts (or
src/lib/schema.ts for TanStack) contains the Better Auth core tables instead
of a sample table.
MongoDB + Mongoose
Environment variable added: MONGODB_URI
Mongoose adds no extra npm scripts. The connection is established in
src/lib/db.ts.
With Auth Module
Environment variables added: JWT_SECRET, JWT_EXPIRES_IN
The auth router is mounted at /auth in src/index.ts.
With Docker Module
The Dockerfile is framework-aware: it uses a Next.js standalone output stage for Next.js projects, a production stage that runs the Nitro .output/ server for TanStack Start, and a Node.js multi-stage build for Express backends. Both full-stack images run npm run build (and Prisma generate for the database variant) and copy the build output to a non-root Alpine production image.
Scripts added to package.json:
npm run docker:build # docker build -t <projectName> .
npm run docker:up # docker compose up -d --build
npm run docker:down # docker compose down
npm run docker:logs # docker compose logs -fSupported Combinations
| Framework | App type | Database | ORM/ODM | Auth | Status |
|---|---|---|---|---|---|
| Express | Backend | none | - | JWT | Yes |
| Express | Backend | PostgreSQL | Prisma | JWT | Yes |
| Express | Backend | PostgreSQL | Drizzle | JWT | Yes |
| Express | Backend | MongoDB | Mongoose | JWT | Yes |
| Next.js | Full-stack | none | - | - | Yes |
| Next.js | Full-stack | PostgreSQL | Prisma | Better Auth | Yes |
| Next.js | Full-stack | PostgreSQL | Drizzle | Better Auth | Yes |
| Next.js | Full-stack | MongoDB | Mongoose | Better Auth | Yes |
| TanStack | Full-stack | none | - | - | Yes |
| TanStack | Full-stack | PostgreSQL | Prisma | Better Auth | Yes |
| TanStack | Full-stack | PostgreSQL | Drizzle | Better Auth | Yes |
| TanStack | Full-stack | MongoDB | Mongoose | Better Auth | Yes |
| NestJS | Backend | none | - | JWT | Yes |
| NestJS | Backend | PostgreSQL | Prisma | JWT | Yes |
| NestJS | Backend | PostgreSQL | Drizzle | JWT | Yes |
| NestJS | Backend | MongoDB | Mongoose | JWT | Yes |