Installation & Setup
This guide provides step-by-step instructions for creating a new ExisJS application with the create-exisjs scaffolding tool or installing the framework manually into an existing TypeScript project.
Prerequisites
Before starting, ensure your system satisfies the following requirements:
- Node.js:
v20.0.0or higher - Package Manager:
npm(v10+),pnpm(v9+),yarn(v1.22+ or berry), orbun(v1.0+) - Operating System: macOS, Linux, or Windows (x64 and ARM64 architectures supported)
Verify your Node.js version by running:
node -vScaffolding a New Project
The quickest way to start a new ExisJS project is with the official create-exisjs scaffolding tool.
Interactive Scaffolding
Run the creation command using your preferred package manager:
# npmnpm create exisjs@latest my-api
# pnpmpnpm create exisjs my-api
# yarnyarn create exisjs my-api
# bunbun create exisjs my-apiYarn 1 can't take a version tag in yarn create. To try a prerelease with Yarn 1, run npx create-exisjs@alpha my-api, then yarn install in the project. Yarn 1 also installs optional dependencies despite --ignore-optional, so a yarn install --production still includes @exisjs/cli and its build tools; use npm ci --omit=dev --omit=optional for production images.
The CLI prompts you with configuration options:
? What is your project named? › my-api? Would you like to use TypeScript? › Yes / No? Would you like to use ESLint? › Yes / No? Which routing paradigm do you prefer? › Functional (Default) / Class-Based (OOP)? Would you like to customize the import alias (`@/*` by default)? › No / YesNon-Interactive Command-Line Flags
For automated environments, Docker initialization, or CI/CD pipelines, you can pass command-line flags to skip interactive prompts:
npx create-exisjs@latest my-api --ts --functional --eslint --yesnpx create-exisjs@latest --help lists every flag.
Complete CLI Flag Reference
| Flag | Description | Default |
|---|---|---|
--ts, --typescript | Configure project with TypeScript | true |
--js, --javascript | Configure project with plain JavaScript | false |
--functional | Configure project using functional paradigm (controller(), route.*) | true |
--oop | Configure project using class-based decorator paradigm (@Controller(), @Get()) | false |
--eslint | Generate ESLint flat config with TypeScript rules | true |
--no-eslint | Skip ESLint setup | false |
--skip-install | Scaffold directory tree and templates without installing dependencies | false |
--skip-git | Skip automatic git init initialization | false |
--yes, -y | Accept default configuration non-interactively | false |
--use-pnpm | Force dependency installation via pnpm | Auto-detected |
--use-bun | Force dependency installation via bun | Auto-detected |
--use-yarn | Force dependency installation via yarn | Auto-detected |
--use-npm | Force dependency installation via npm | Auto-detected |
Generated Project Layout
Once the scaffolding finishes, your project contains the standard ExisJS directory layout:
my-api/├── .agents/│ └── rules/│ └── AGENTS.md # Architecture rules and agent guidelines├── src/│ ├── common/│ │ └── guards/│ │ └── auth.guard.ts # Reusable route guards│ ├── config/│ │ └── env.ts # Type-safe environment validation (tex.env)│ ├── cron/│ │ └── cleanup.ts # Scheduled background tasks│ ├── database/│ │ └── db.ts # Database lifecycle and connection│ └── http/│ ├── health/│ │ └── route.ts # Health check endpoint (/health)│ ├── users/│ │ ├── route.ts # User routes (/users)│ │ ├── schema.ts # Input validation schemas (tex.*)│ │ └── service.ts # Service layer logic│ ├── boundary.ts # Root middleware, CORS & error boundary│ ├── route.ts # Root route handler (/)│ └── server.ts # Application lifecycle (onStart / onClose)├── tests/│ └── users.test.ts # End-to-end test suite├── .env # Environment variables├── .gitignore├── .prettierrc├── eslint.config.mjs # ESLint configuration (when selected)├── exis.config.ts # Framework configuration├── package.json└── tsconfig.jsonManual Installation
To install ExisJS into an existing repository without scaffolding:
Step 1: Install Core Dependencies
npm install exisjsnpm install -D @exisjs/cli typescript @types/node prettierStep 2: Configure tsconfig.json
Create or update tsconfig.json to configure module resolution and metadata reflection:
{ "compilerOptions": { "target": "ES2022", "lib": ["esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "paths": { "@/*": ["./src/*"] }, "types": ["node"] }, "include": [ "src/**/*.ts", "tests/**/*.ts", "*.config.ts", "*.ts" ], "exclude": ["node_modules", ".exis", "dist", "build"]}[!NOTE]
experimentalDecorators is required when using the class-based (OOP) paradigm; emitDecoratorMetadata is harmless but not used by the ExisJS toolchain, so inject constructor dependencies with @Inject(Token). This applies to the class-based (OOP) paradigm (@Controller(), @Injectable()).
Step 3: Create exis.config.ts
Create an exis.config.ts file in the project root:
import type { ExisConfig } from 'exisjs/config'
const config: ExisConfig = { port: Number(process.env.PORT) || 4000, host: '0.0.0.0',
// Credentialed requests need explicit origins (comma-separated CORS_ORIGIN). // Without it, any origin may call the API, but without cookies. cors: process.env.CORS_ORIGIN ? { origin: process.env.CORS_ORIGIN.split(','), credentials: true } : { origin: '*' },
logger: { level: process.env.NODE_ENV === 'production' ? 'info' : 'debug', pretty: process.env.NODE_ENV !== 'production', },
helmet: { enabled: true }, compression: true,
// Swagger UI at /docs, development only docs: { enabled: process.env.NODE_ENV !== 'production' },}
export default configStep 4: Configure NPM Scripts
Add the standard ExisJS CLI commands to package.json:
{ "scripts": { "dev": "exisjs dev", "build": "exisjs build", "start": "exisjs start", "routes": "exisjs routes", "test": "exisjs test", "doctor": "exisjs doctor" }}Verifying the Installation
1. Create a Health Check Endpoint
Create src/http/health/route.ts:
Option A: Functional Route
import { controller, route } from 'exisjs/router'
export default controller({ check: route.get('/', { summary: 'Service health check', handle: () => ({ status: 'ok', timestamp: new Date().toISOString(), }), }),})Option B: Class-Based Route
import { Controller, Get, ApiOperation } from 'exisjs/decorators'
@Controller()export default class HealthController { @Get('/') @ApiOperation({ summary: 'Service health check' }) check() { return { status: 'ok', timestamp: new Date().toISOString(), } }}2. Start the Development Server
Execute the dev script:
npm run devOutput:
[exis] starting development server (v0.9.0)...EXIS ready in 125 ms
→ Local: http://localhost:4000/→ Docs: http://localhost:4000/docs→ Network: http://127.0.0.1:4000/3. Verify the Endpoint
Send an HTTP GET request to verify the route:
curl http://localhost:4000/healthExpected JSON response:
{ "status": "ok", "timestamp": "2026-10-02T11:35:00.000Z"}Open http://localhost:4000/docs in your browser to inspect the interactive Swagger UI.
Next Steps
- Project Structure: Review directory conventions for routes, boundaries, services, and database models.
- Routing & Endpoints: Learn how folders map to HTTP verbs, path params, and catch-all routes.
- Validation: Build typed schemas with
texfor body, query, and header validation. - Configuration Reference: Complete reference of all options in
exis.config.ts.