Next.js
Build full-stack, type-safe applications with Igniter.js and Next.js App Router.
Igniter.js integrates seamlessly with Next.js to provide end-to-end type safety between your React components and API layer. This guide walks you through building a complete full-stack application with the Next.js App Router.
The combination delivers the best of both worlds: Next.js's excellent developer experience with React Server Components, paired with Igniter.js's automatic type inference and runtime safety. You'll write less boilerplate, catch more bugs at compile time, and ship features faster.
App Router Required
This guide uses Next.js 15+ with the App Router. The Pages Router is not supported.
Quick Start
The fastest way to start is using the official CLI, which scaffolds a complete application with all necessary configuration:
npx @igniter-js/cli@latest initpnpm dlx @igniter-js/cli@latest inityarn dlx @igniter-js/cli@latest initbunx @igniter-js/cli@latest initYour app runs at http://localhost:3000. API is at http://localhost:3000/api/v1, and interactive docs at http://localhost:3000/api/v1/docs 🚀
Direct Command
If you prefer to skip the interactive prompts, you can specify your project name and framework directly:
npx @igniter-js/cli@latest init my-nextjs-app --framework nextjspnpm dlx @igniter-js/cli@latest init my-nextjs-app --framework nextjsyarn dlx @igniter-js/cli@latest init my-nextjs-app --framework nextjsbunx @igniter-js/cli@latest init my-nextjs-app --framework nextjsThis command will create a Next.js project with all Igniter.js features pre-configured.
Manual Setup
Complete Next.js Setup Guide
Prerequisites
Before you begin, ensure you have:
- Node.js 22.0+
- Next.js 15.0+ with App Router
- TypeScript 5.0+
Install Core Package
Install Igniter.js and Zod for schema validation:
npm install @igniter-js/core zodpnpm add @igniter-js/core zodyarn add @igniter-js/core zodbun add @igniter-js/core zodZod provides excellent TypeScript inference and runtime validation, making it the recommended choice for Igniter.js projects.
Define Application Context
The context defines dependencies available throughout your API (database, services, etc.). 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
// auth: AuthService
}
/**
* 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 with configuration. 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.NEXT_PUBLIC_IGNITER_API_URL || 'http://localhost:3000',
basePATH: process.env.NEXT_PUBLIC_IGNITER_API_BASE_PATH || '/api/v1',
})
.docs({
info: {
title: 'My Next.js API',
version: '1.0.0',
description: 'API built with Igniter.js',
}
})
.create()The builder pattern makes it easy to add features later like .store() (Redis), .jobs() (background tasks), .logger(), and .telemetry().
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!',
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 AppRouterThe type export enables the type-safe client without exposing server implementation.
Create Next.js API Route
Connect the router to Next.js using the adapter. Create src/app/api/v1/[[...all]]/route.ts:
import { AppRouter } from '@/igniter.router'
import { nextRouteHandlerAdapter } from '@igniter-js/core/adapters'
export const { GET, POST, PUT, DELETE } = nextRouteHandlerAdapter(AppRouter)The [[...all]] catch-all route handles all methods and paths under /api/v1/.
Step 7: Generate Type-Safe Client
Create the client for frontend usage at 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.NEXT_PUBLIC_IGNITER_API_URL || 'http://localhost:3000',
basePATH: process.env.NEXT_PUBLIC_IGNITER_API_BASE_PATH || '/api/v1',
router: () => {
if (typeof window === 'undefined') {
return require('./igniter.router').AppRouter
}
return require('./igniter.schema').AppRouterSchema
},
})
export type ApiClient = typeof apiThis client works in both Server and Client Components with full type safety.
Usage in Components
Server Components
Use direct API calls in Server Components:
import { api } from '@/igniter.client'
export default async function HomePage() {
const { message } = await api.example.hello.query()
return <div>Message: {message}</div>
}Client Components
Use React hooks for automatic loading/error states:
'use client'
import { api } from '@/igniter.client'
export function ExampleComponent() {
const { data, isLoading, error } = api.example.hello.useQuery()
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>Message: {data.message}</div>
}Generating Schema and Docs
Igniter.js can automatically generate OpenAPI schemas and TypeScript types for your API.
When to Generate Schema
Critical: You MUST run schema generation BEFORE using the client in your frontend. The client depends on the generated schema to function correctly.
Run this command whenever you modify your API structure (add/remove/modify controllers or actions) OR before using the client for the first time.
Generate Schema
Run this command whenever you make changes to your API structure:
npx @igniter-js/cli@latest generate schemapnpm dlx @igniter-js/cli@latest generate schemayarn dlx @igniter-js/cli@latest generate schemabunx @igniter-js/cli@latest generate schemaThis creates:
src/igniter.schema.ts- Type-safe schema for client-side usagesrc/docs/openapi.json- OpenAPI 3.0 specification
Generate OpenAPI Documentation
To generate or update the OpenAPI specification and interactive documentation:
npx @igniter-js/cli@latest generate docspnpm dlx @igniter-js/cli@latest generate docsyarn dlx @igniter-js/cli@latest generate docsbunx @igniter-js/cli@latest generate docsUpdate Igniter Config
Import the generated OpenAPI schema in src/igniter.ts:
import { Igniter } from '@igniter-js/core'
import { createIgniterAppContext } from './igniter.context'
import openapi from './docs/openapi.json'
export const igniter = Igniter
.context(createIgniterAppContext())
.config({
baseURL: process.env.NEXT_PUBLIC_IGNITER_API_URL || 'http://localhost:3000',
basePATH: process.env.NEXT_PUBLIC_IGNITER_API_BASE_PATH || '/api/v1',
})
.docs({
openapi, // ← Add generated OpenAPI
info: {
title: 'My Next.js API',
version: '1.0.0',
description: 'API built with Igniter.js',
}
})
.create()Igniter Studio (API Playground)
Igniter.js includes an interactive API playground called Igniter Studio, powered by Scalar. 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 in the browser
- See auto-generated examples
The playground updates automatically as you add new endpoints or modify existing ones. It's perfect for API development and testing without needing external tools like Postman.
Project Structure
Here's the recommended structure: