Skip to main content
The Ignitor class serves as the main entry point for creating and managing AdonisJS applications. It provides a fluent API for bootstrapping your application in different environments like web servers, CLI commands, tests, and REPL.

Basic Usage

The Ignitor is typically used in your application’s entry point files:
bin/server.ts
import { Ignitor } from '@adonisjs/core'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor.httpServer().start()

Constructor

The Ignitor constructor accepts two parameters:
constructor(appRoot: URL, options?: IgnitorOptions)
appRoot
URL
required
The root URL of your application, typically new URL('../', import.meta.url) from your entry point file.
options
IgnitorOptions
Optional configuration object:

Creating Applications

The Ignitor provides different process classes for various environments:

HTTP Server

Create an HTTP server process for handling web requests:
bin/server.ts
import { Ignitor } from '@adonisjs/core'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor.httpServer().start()
The HTTP server process:
  • Creates an application instance in the 'web' environment
  • Initializes and boots the application
  • Starts the Node.js HTTP server
  • Listens on the configured host and port (from HOST and PORT environment variables)
By default, the server listens on 0.0.0.0:3333. You can override this using the HOST and PORT environment variables.

Custom HTTP Server

You can provide a custom server factory for HTTPS or other configurations:
bin/server.ts
import { Ignitor } from '@adonisjs/core'
import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor.httpServer().start((handler) => {
  return createServer({
    key: readFileSync('./key.pem'),
    cert: readFileSync('./cert.pem')
  }, handler)
})

Ace CLI

Create an Ace process for running CLI commands:
bin/console.ts
import { Ignitor } from '@adonisjs/core'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor.ace().handle(process.argv.slice(2))
The Ace process:
  • Creates an application instance in the 'console' environment
  • Initializes the application
  • Conditionally boots the app (only for commands that need it)
  • Handles command execution
  • Terminates the app after command completion

Configuring Ace

You can configure the Ace kernel before handling commands:
bin/console.ts
import { Ignitor } from '@adonisjs/core'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor
  .ace()
  .configure((app) => {
    // Configure ace kernel
    // Register custom commands, etc.
  })
  .handle(process.argv.slice(2))

Test Runner

Create a test runner process for executing tests:
bin/test.ts
import { Ignitor } from '@adonisjs/core'
import { configure, processCLIArgs, run } from '@japa/runner'

const ignitor = new Ignitor(new URL('../', import.meta.url))

await ignitor.testRunner().run(async () => {
  configure({
    files: ['tests/**/*.spec.ts']
  })
  
  processCLIArgs(process.argv.splice(2))
  await run()
})

Source Code Reference

The Ignitor class is defined in src/ignitor/main.ts:36:
src/ignitor/main.ts
export class Ignitor {
  #options: IgnitorOptions
  #appRoot: URL
  #app?: ApplicationService
  #tapCallbacks: Set<(app: ApplicationService) => void> = new Set()

  constructor(appRoot: URL, options: IgnitorOptions = {}) {
    this.#appRoot = appRoot
    this.#options = options
  }

  /**
   * Create an instance of AdonisJS application
   */
  createApp(environment: AppEnvironments) {
    this.#app = new Application(this.#appRoot, {
      environment,
      importer: this.#options.importer
    })
    
    setApp(this.#app)
    this.#runTapCallbacks(this.#app)
    return this.#app
  }

  /**
   * Tap to access the application class instance
   */
  tap(callback: (app: ApplicationService) => void): this {
    this.#tapCallbacks.add(callback)
    return this
  }

  /**
   * Get instance of the HTTPServerProcess
   */
  httpServer() {
    return new HttpServerProcess(this)
  }

  /**
   * Get an instance of the AceProcess class
   */
  ace() {
    return new AceProcess(this)
  }

  /**
   * Get an instance of the TestRunnerProcess class
   */
  testRunner() {
    return new TestRunnerProcess(this)
  }

  /**
   * Terminates the app
   */
  async terminate() {
    await this.#app?.terminate()
  }
}

Methods

createApp()

Creates an application instance for a specific environment:
createApp(environment: 'web' | 'console' | 'test' | 'repl'): ApplicationService
environment
AppEnvironments
required
The environment in which to create the app:
  • 'web' - For HTTP server processes
  • 'console' - For CLI commands
  • 'test' - For test runner
  • 'repl' - For interactive REPL
You typically don’t call createApp() directly. Instead, use one of the process methods (httpServer(), ace(), testRunner()) which handle app creation automatically.

tap()

Register a callback that executes when the application is created:
tap(callback: (app: ApplicationService) => void): this
const ignitor = new Ignitor(new URL('../', import.meta.url))

ignitor.tap((app) => {
  // Access the application instance
  console.log('App created:', app.getState())
})

await ignitor.httpServer().start()

getApp()

Retrieve the created application instance:
getApp(): ApplicationService | undefined
const ignitor = new Ignitor(new URL('../', import.meta.url))
const app = ignitor.createApp('web')

console.log(ignitor.getApp() === app) // true

terminate()

Terminate the application gracefully:
await terminate(): Promise<void>
const ignitor = new Ignitor(new URL('../', import.meta.url))

// Later...
await ignitor.terminate()

Process Classes

HttpServerProcess

Manages the HTTP server lifecycle. Located at src/ignitor/http.ts:32.
export class HttpServerProcess {
  constructor(ignitor: Ignitor) {}

  async start(
    serverCallback?: (handler) => NodeHttpsServer | NodeHttpServer
  ) {
    const app = this.#ignitor.createApp('web')
    
    await app.init()
    await app.boot()
    await app.start(async () => {
      const server = await app.container.make('server')
      await server.boot()
      
      const httpServer = createHTTPServer(server.handle.bind(server))
      server.setNodeServer(httpServer)
      
      await this.#listen(httpServer)
      this.#monitorAppAndServer(httpServer, app, logger)
    })
  }
}

AceProcess

Manages the Ace CLI lifecycle. Located at src/ignitor/ace.ts:28.
export class AceProcess {
  constructor(ignitor: Ignitor) {}

  configure(callback: (app: ApplicationService) => void): this {
    this.#configureCallback = callback
    return this
  }

  async handle(argv: string[]) {
    const app = this.#ignitor.createApp('console')
    await app.init()
    
    const kernel = createAceKernel(app, commandName)
    app.container.bindValue('ace', kernel)
    
    // Boot app only for commands that need it
    kernel.loading(async (metaData) => {
      if (metaData.options.startApp && !app.isReady) {
        await app.boot()
        await app.start(() => {})
      }
    })
    
    await this.#configureCallback(app)
    await kernel.handle(argv)
    
    // Terminate unless it's a long-running command
    if (!mainCommand?.staysAlive) {
      await app.terminate()
    }
  }
}

Application Lifecycle Hooks

The Ignitor manages the application through distinct lifecycle phases:
1

Creation

Application instance is created with the specified environment
2

Initialization

Application loads configuration and registers service providers
3

Boot

Service providers’ boot methods are called
4

Start

Application starts and service providers’ ready methods are called
5

Termination

Application and all services are gracefully shut down

Next Steps

Application Lifecycle

Learn about application states and lifecycle hooks

Service Providers

Understand how to register services with the container