Express
Build type-safe REST APIs with Igniter.js and Express.js, the minimal and flexible Node.js web framework.
Express.js is the most popular Node.js web framework, known for its minimalist approach and robust middleware ecosystem. When combined with Igniter.js, you maintain Express's simplicity and flexibility while gaining end-to-end type safety, automatic schema generation, and a modern API design experience.
This guide shows you how to integrate Igniter.js with Express to build production-ready REST APIs. You'll learn how to leverage Express's mature ecosystem (middleware, routing, error handling) alongside Igniter.js's type-safe controllers and automatic documentation.
Perfect for REST APIs
Express + Igniter.js is ideal for building traditional REST APIs, microservices, and backends that need Express's mature middleware ecosystem.
Quick Start
The fastest way to start is using the official CLI, which scaffolds a complete Express application with Igniter.js:
npx create-igniter-app@latest my-app --template express
cd my-app
npm install
npm run devpnpm create igniter-app my-app --template express
cd my-app
pnpm install
pnpm devyarn create igniter-app my-app --template express
cd my-app
yarn install
yarn devbunx create-igniter-app my-app --template express
cd my-app
bun install
bun devYour API runs at http://localhost:3000/api/v1, and interactive docs at http://localhost:3000/api/v1/docs 🚀
Manual Setup
Complete Express Setup Guide
Prerequisites
Before you begin, ensure you have:
- Node.js 18.0+ (20.0+ recommended)
- Express 4.0+
- TypeScript 5.0+
Install Dependencies
Install Igniter.js, Express, and Zod for schema validation:
npm install @igniter-js/core express zod
npm install -D @types/express tsxpnpm add @igniter-js/core express zod
pnpm add -D @types/express tsxyarn add @igniter-js/core express zod
yarn add -D @types/express tsxbun add @igniter-js/core express zod
bun add -D @types/expressThe tsx package enables running TypeScript directly during development without a build step.
Define Application Context
The context defines dependencies available throughout your API. Create src/igniter.context.ts:
/**
* Application Context Type
* Defines what dependencies are available to all API handlers
*/
export interface AppContext {
// Add your dependencies here, e.g.:
// db: PrismaClient
// logger: Logger
}
/**
* Context Factory
* Creates the context instance passed to handlers
*/
export function createIgniterAppContext(): AppContext {
return {
// Initialize dependencies here
}
}Initialize Igniter.js
Create the main Igniter instance. Create src/igniter.ts:
import { Igniter } from '@igniter-js/core'
import { createIgniterAppContext } from './igniter.context'
export const igniter = Igniter
.context(createIgniterAppContext())
.config({
baseURL: process.env.IGNITER_API_URL || 'http://localhost:3000',
basePATH: process.env.IGNITER_API_BASE_PATH || '/api/v1',
})
.docs({
info: {
title: 'My Express API',
version: '1.0.0',
description: 'REST API built with Express and Igniter.js',
}
})
.create()Create Your First Controller
Controllers group related endpoints. Create src/features/example/controllers/example.controller.ts:
import { igniter } from '@/igniter'
export const exampleController = igniter.controller({
name: 'Example',
path: '/example',
actions: {
hello: igniter.query({
path: '/hello',
handler: async ({ response }) => {
return response.success({
message: 'Hello from Igniter.js with Express!',
timestamp: new Date().toISOString()
})
},
}),
},
})Create barrel export at src/features/example/index.ts:
export * from './controllers/example.controller'This creates GET /api/v1/example/hello with fully typed responses.
Create Application Router
The router assembles all controllers. Create src/igniter.router.ts:
import { igniter } from './igniter'
import { exampleController } from './features/example'
export const AppRouter = igniter.router({
controllers: {
example: exampleController
}
})
export type AppRouterType = typeof AppRouterSet Up Express Server
Connect the router to Express using the adapter. Create src/index.ts:
import express from 'express'
import { expressAdapter } from '@igniter-js/core/adapters'
import { AppRouter } from './igniter.router'
const app = express()
const IGNITER_API_BASE_PATH = process.env.IGNITER_API_BASE_PATH || '/api/v1'
const PORT = process.env.PORT || 3000
// Mount the Igniter.js router
app.use(IGNITER_API_BASE_PATH, expressAdapter(AppRouter.handler))
// Start the server
app.listen(PORT, () => {
console.log(`🚀 Server running at http://localhost:${PORT}`)
})The expressAdapter converts Igniter.js's universal handler into Express-compatible middleware.
Step 7: Add Development Scripts
Update your package.json:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
}Now run npm run dev to start the development server with hot reload!
Using Express Middleware
Express middleware works seamlessly with Igniter.js. Add middleware before mounting the Igniter router:
import express from 'express'
import cors from 'cors'
import helmet from 'helmet'
import compression from 'compression'
import { expressAdapter } from '@igniter-js/core/adapters'
import { AppRouter } from './igniter.router'
const app = express()
// Add Express middleware
app.use(cors())
app.use(helmet())
app.use(compression())
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// Add custom middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`)
next()
})
// Mount Igniter.js router
app.use('/api/v1', expressAdapter(AppRouter.handler))
app.listen(3000)Middleware like CORS, security headers, compression, and logging work exactly as you'd expect in Express.
Type-Safe Client
Create a type-safe client for consuming your API. Create src/igniter.client.ts:
import { createIgniterClient } from '@igniter-js/core/client'
import type { AppRouterType } from './igniter.router'
export const api = createIgniterClient<AppRouterType>({
baseURL: process.env.IGNITER_API_URL || 'http://localhost:3000',
basePATH: process.env.IGNITER_API_BASE_PATH || '/api/v1',
router: () => require('./igniter.router').AppRouter,
})
export type ApiClient = typeof apiUse it anywhere in your application:
// Fully typed request and response
const { message } = await api.example.hello.query()Igniter Studio (API Playground)
Igniter.js includes an interactive API playground called Igniter Studio. It's automatically available at /api/v1/docs when you configure the .docs() method.
To access it:
- Start your dev server:
npm run dev - Navigate to
http://localhost:3000/api/v1/docs - You'll see an interactive interface where you can:
- Browse all API endpoints
- View request/response schemas
- Test endpoints directly
- See auto-generated examples
The playground updates automatically as you add endpoints.
Environment Variables
Create a .env file for configuration:
PORT=3000
IGNITER_API_BASE_PATH=/api/v1
IGNITER_API_URL=http://localhost:3000
NODE_ENV=developmentProject Structure
Here's the recommended structure: