ZZuro Docs

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 init

Installs 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.json
  • src/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 dev

Example request:

GET /health

Example response:

{
  "status": "ok",
  "timestamp": "2026-03-12T10:00:00.000Z"
}

How It Works

  1. Client calls the API.
  2. Express app (app.ts) runs middleware (helmet, cors, json).
  3. Request is routed to /health or /api/*.
  4. Runtime uses logger.ts and validated config from env.ts.
  5. Response is returned.

Configuration

PORT=3000
NODE_ENV=development

PORT: 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 in src/routes/index.ts).

Advanced Usage

Optional Prettier setup during init:

# prompt: Setup Prettier? -> Yes

This 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 uploads

Example Use Cases

  • User authentication foundation: scaffold first, then add auth.
  • Webhook processing service: start with /api routes and structured logging.
  • Background jobs admin API: bootstrap quickly with health checks and env validation.
  • File uploads backend: scaffold with init, then add uploads and database.

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 variables
  • express.json() and express.urlencoded() body parsers
  • /health endpoint returning { status: "ok", timestamp } for uptime monitoring
  • /api namespace routed to src/routes/index.ts

src/server.ts — the process entry point. Calls app.listen() and handles:

  • Graceful shutdown on SIGTERM and SIGINT signals
  • 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:

OrderMiddlewarePurpose
1helmet()Sets 11 security HTTP headers
2cors()Handles CORS preflight and headers
3express.json()Parses JSON request bodies
4express.urlencoded()Parses form-encoded bodies
5Route handlersYour application logic

Troubleshooting

Port 3000 is already in use Change the port in your .env file:

PORT=3001

Environment 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.

On this page