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 init
pnpm dlx @igniter-js/cli@latest init
yarn dlx @igniter-js/cli@latest init
bunx @igniter-js/cli@latest init

Your 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 nextjs
pnpm dlx @igniter-js/cli@latest init my-nextjs-app --framework nextjs
yarn dlx @igniter-js/cli@latest init my-nextjs-app --framework nextjs
bunx @igniter-js/cli@latest init my-nextjs-app --framework nextjs

This 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 zod
pnpm add @igniter-js/core zod
yarn add @igniter-js/core zod
bun add @igniter-js/core zod

Zod 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:

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:

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:

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:

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:

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 AppRouter

The 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:

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:

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 api

This client works in both Server and Client Components with full type safety.

Usage in Components

Server Components

Use direct API calls in Server Components:

app/page.tsx
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:

components/example.tsx
'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 schema
pnpm dlx @igniter-js/cli@latest generate schema
yarn dlx @igniter-js/cli@latest generate schema
bunx @igniter-js/cli@latest generate schema

This creates:

  • src/igniter.schema.ts - Type-safe schema for client-side usage
  • src/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 docs
pnpm dlx @igniter-js/cli@latest generate docs
yarn dlx @igniter-js/cli@latest generate docs
bunx @igniter-js/cli@latest generate docs

Update Igniter Config

Import the generated OpenAPI schema in src/igniter.ts:

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:

  1. Start your dev server: npm run dev
  2. Navigate to http://localhost:3000/api/v1/docs
  3. 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:

igniter.ts
igniter.context.ts
igniter.router.ts
igniter.client.ts
igniter.schema.ts

Next Steps