Init
Published Oct 2, 2025 | Updated Mar 13, 2026
Add the init module to scaffold a production-ready Express + TypeScript backend
Overview
Scaffold a production-ready Express + TypeScript backend foundation in one command.
Install
npx zuro add initInstalls and scaffolds the core backend module (for fresh projects, use npx zuro-cli init).
What This Generates
src/
├ app.ts
├ server.ts
├ env.ts
├ routes/
│ └ index.ts
└ lib/
└ logger.ts
.env
.gitignore
package.json
tsconfig.json
zuro.jsonsrc/app.ts: sets up Express, Helmet, CORS, JSON body parsing,/api, and/health.src/server.ts: starts the server and handles graceful shutdown.src/env.ts: validates environment variables with Zod.src/routes/index.ts: root API router.src/lib/logger.ts: configures Pino logging.
Quick Example
npx zuro-cli init my-api
cd my-api
npm run devExample request:
GET /healthExample response:
{
"status": "ok",
"timestamp": "2026-03-12T10:00:00.000Z"
}How It Works
- Client calls the API.
- Express app (
app.ts) runs middleware (helmet,cors,json). - Request is routed to
/healthor/api/*. - Runtime uses
logger.tsand validated config fromenv.ts. - Response is returned.
Configuration
PORT=3000
NODE_ENV=developmentPORT: Server port used by server.ts.
NODE_ENV: Environment mode (development, test, production) used by logger and runtime behavior.
API Reference
GET /health: returns service health and timestamp./api/*: root API namespace (empty by default, add endpoints insrc/routes/index.ts).
Advanced Usage
Optional Prettier setup during init:
# prompt: Setup Prettier? -> YesThis adds prettier, .prettierrc, .prettierignore, and scripts:
{
"scripts": {
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}Integrate additional modules:
npx zuro-cli add database
npx zuro-cli add auth
npx zuro-cli add uploadsExample Use Cases
- User authentication foundation: scaffold first, then add
auth. - Webhook processing service: start with
/apiroutes and structured logging. - Background jobs admin API: bootstrap quickly with health checks and env validation.
- File uploads backend: scaffold with
init, then adduploadsanddatabase.
Understanding Generated Files
src/app.ts — the Express application factory. Sets up:
helmet()for HTTP security headers (XSS, clickjacking, MIME sniffing protection)cors()configured from environment variablesexpress.json()andexpress.urlencoded()body parsers/healthendpoint returning{ status: "ok", timestamp }for uptime monitoring/apinamespace routed tosrc/routes/index.ts
src/server.ts — the process entry point. Calls app.listen() and handles:
- Graceful shutdown on
SIGTERMandSIGINTsignals - Draining active connections before exit
src/env.ts — environment variable validation using Zod. Reads process.env at startup and throws a descriptive error if required variables are missing or malformed. This prevents runtime surprises from misconfigured deployments.
// Example of what env.ts validates
const envSchema = z.object({
PORT: z.coerce.number().default(3000),
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
});src/routes/index.ts — the root API router. Add your feature routes here:
import { Router } from "express";
const router = Router();
// Add your routes
router.use("/users", usersRouter);
export default router;src/lib/logger.ts — Pino logger instance. Configured for pretty output in development and JSON output in production (detected via NODE_ENV).
import { logger } from "./lib/logger";
logger.info({ userId: "123" }, "User signed in");Middleware Stack
The generated middleware stack runs in this order on every request:
| Order | Middleware | Purpose |
|---|---|---|
| 1 | helmet() | Sets 11 security HTTP headers |
| 2 | cors() | Handles CORS preflight and headers |
| 3 | express.json() | Parses JSON request bodies |
| 4 | express.urlencoded() | Parses form-encoded bodies |
| 5 | Route handlers | Your application logic |
Troubleshooting
Port 3000 is already in use
Change the port in your .env file:
PORT=3001Environment variable validation failed
src/env.ts throws on startup if a required variable is missing. Check your .env file matches the schema in src/env.ts. Each module that adds env vars (database, auth) appends to this schema automatically.
Cannot find module '@/...'
Ensure your tsconfig.json includes the path alias. The generated config maps @/* to ./src/*:
{
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
}
}CORS errors from frontend
Update the CORS origin in src/app.ts to match your frontend URL:
cors({ origin: env.CORS_ORIGIN })Then add CORS_ORIGIN=http://localhost:5173 to your .env.