adonisjs/core

AdonisJS is a TypeScript-first web framework for building web apps and API servers. It comes with support for testing, modern tooling, an ecosystem of official packages, and more.

18,867 stars TypeScript 6 components

TypeScript web framework that bootstraps applications with modules, commands, and providers

Application startup begins with Ignitor.createApp() which loads the container and environment variables. Service providers are then loaded and booted in sequence, registering bindings and initializing modules. For web mode, the HTTP server starts and handles requests through the router. For console mode, the Ace kernel processes CLI commands. Throughout execution, the container resolves dependencies and the configuration system provides typed settings.

Under the hood, the system uses 2 feedback loops, 2 data pools, 3 control points to manage its runtime behavior.

A 6-component repository. 193 files analyzed. Data flows through 6 distinct pipeline stages.

How Data Flows Through the System

Application startup begins with Ignitor.createApp() which loads the container and environment variables. Service providers are then loaded and booted in sequence, registering bindings and initializing modules. For web mode, the HTTP server starts and handles requests through the router. For console mode, the Ace kernel processes CLI commands. Throughout execution, the container resolves dependencies and the configuration system provides typed settings.

  1. Initialize Application — Ignitor.createApp() creates an Application instance, loads environment variables from .env files using @adonisjs/env, and initializes the IoC container for dependency management [IgnitorOptions → ApplicationService]
  2. Load Providers — Application.init() processes the providers array from adonisrc.ts, dynamically imports each provider class, and registers them in dependency order for later booting [ProviderNode → ApplicationService]
  3. Boot Services — Application.boot() calls each provider's register() method to bind services to the container, then calls boot() methods to initialize services with their dependencies resolved [ApplicationService → ApplicationService]
  4. Resolve Configuration — ConfigProviders are resolved by calling their resolver functions with the booted application instance, providing typed configuration objects to modules and services [ConfigProvider → Configuration values]
  5. Start Application — For web mode, HTTP server starts listening on configured port using @adonisjs/http-server. For console mode, Ace kernel processes command-line arguments and executes the specified command [ApplicationService → Running server or command result]
  6. Handle Requests/Commands — HTTP requests flow through middleware and route handlers using the Router. CLI commands are parsed by Kernel, instantiated as BaseCommand subclasses, and executed with application context [HTTP Request or CLI arguments → HTTP Response or Command output]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

ApplicationService src/types.ts
Application instance with container: Container, env: Env, config: ConfigStore, logger: Logger, and lifecycle methods init(), boot(), start(), terminate()
Created by Ignitor, initialized with container and environment, booted with providers, then used throughout application lifetime
ConfigProvider src/types.ts
Object with type: 'provider' and resolver: (app: ApplicationService) => Promise<T> function that returns configuration
Defined at startup, resolved after application boot when configuration is needed
CommandOptions types/ace.ts
BaseCommandOptions extended with startApp?: boolean flag to control whether command should bootstrap the application
Created when parsing CLI arguments, used during command execution to determine bootstrap behavior
ProviderNode types/app.ts
Object with file: () => Promise<Provider> function that dynamically imports a service provider class
Registered during application setup, loaded and instantiated during boot phase, then used to provide services

Hidden Assumptions

Things this code relies on but never validates. These are the things that cause silent failures when the system changes.

critical Contract unguarded

Core provider imports (app_provider, http_server, etc.) will always exist and export valid provider classes, but the code uses dynamic imports without checking if the imported modules have the expected structure

If this fails: If a core provider module is missing or exports malformed provider class, application bootstrap fails with cryptic import errors instead of clear 'missing provider' messages

factories/core/ignitor.ts:mergeCoreProviders
critical Ordering unguarded

Core providers array order ([app_provider, http_server, bodyparser, hash, encryption, logger]) matches dependency requirements, but no validation ensures HTTP server depends on app_provider or bodyparser depends on HTTP server

If this fails: If core providers are reordered or custom providers inserted incorrectly, services may be accessed before their dependencies are registered, causing runtime binding resolution failures

factories/core/ignitor.ts:mergeCoreProviders
warning Environment weakly guarded

The Youch package will always be available for error formatting when needed, using dynamic import without fallback validation

If this fails: If Youch package is missing or incompatible in production, error handling silently falls back to console.error without notifying that pretty printing failed, masking the root cause

index.ts:prettyPrintError
critical Contract unguarded

setApp() will be called exactly once before any other service accesses the app variable, but no validation prevents multiple calls or access before initialization

If this fails: If setApp() is never called or called multiple times, services get undefined app reference or inconsistent app instances, leading to 'Cannot read property of undefined' errors or stale service state

services/app.ts:setApp
warning Domain unguarded

All stub files use consistent placeholder syntax that can be processed by the same template engine, but no validation checks stub format before processing

If this fails: If stub files use incompatible template syntax (different placeholder formats, malformed templates), stub processing produces corrupted output code without validation errors

factories/stubs.ts:prepare
warning Contract unguarded

Command array passed to handle() has string elements where first element is valid command name, but no validation of array structure or command existence before processing

If this fails: If handle() receives malformed command array (undefined elements, wrong types, non-existent commands), kernel fails with array access errors instead of helpful 'command not found' messages

modules/ace/main.ts:Kernel.handle
warning Resource unguarded

Preload actions will complete successfully and not throw exceptions that would halt application startup, but no error boundaries wrap preload execution

If this fails: If any preload action throws an exception, entire application bootstrap fails without isolating the problematic preload, making it hard to identify which custom initialization caused the failure

factories/core/ignitor.ts:preload
warning Temporal unguarded

All imported error modules (aceErrors, envErrors, etc.) export non-overlapping error name properties, but no validation prevents error name conflicts during object spreading

If this fails: If multiple modules export errors with same names, later imports silently overwrite earlier ones in the errors object, causing wrong error types to be thrown or caught

index.ts:errors
warning Environment unguarded

import.meta.dirname will always point to the correct stubs directory and remain stable across different deployment environments and bundling tools

If this fails: If bundling or deployment changes import.meta.dirname resolution, stub loading fails silently or loads wrong templates, causing generated code to be incorrect or empty

stubs/main.ts:stubsRoot
info Scale unguarded

Number of preload actions will remain reasonable (under 100s) since they're stored in memory array and executed sequentially without batching or limits

If this fails: If hundreds of preload actions are registered, application startup becomes extremely slow due to sequential execution, and memory usage grows linearly with no cleanup mechanism

factories/core/ignitor.ts:preloadActions

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

IoC Container (registry)
Central dependency registry that stores service bindings, singletons, and factory functions, resolved throughout application lifetime
Application State (state-store)
Singleton ApplicationService instance that holds environment, config, logger, and container references used across all modules

Feedback Loops

Delays

Control Points

Technology Stack

@adonisjs/ace (framework)
Powers the CLI system with command parsing, argument validation, help generation, and command registration
@adonisjs/application (framework)
Core application container and lifecycle management including service providers, IoC container, and environment handling
@adonisjs/http-server (framework)
HTTP server implementation with routing, middleware support, request/response handling for web applications
@adonisjs/bodyparser (library)
Request body parsing middleware for JSON, form data, and multipart content in HTTP requests
@boringnode/encryption (library)
Encryption services with multiple drivers (AES-256-CBC, AES-256-GCM, ChaCha20-Poly1305) for data security
youch (library)
Pretty-prints error stack traces with syntax highlighting for better developer experience during debugging
@japa/runner (testing)
Test runner for the framework's own test suite with plugins for assertions, file system testing, and snapshots

Key Components

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Repository Repositories

Frequently Asked Questions

What is core used for?

TypeScript web framework that bootstraps applications with modules, commands, and providers adonisjs/core is a 6-component repository written in TypeScript. Data flows through 6 distinct pipeline stages. The codebase contains 193 files.

How is core architected?

core is organized into 4 architecture layers: Ignitor Bootstrap, Modules, Commands, Factories. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through core?

Data moves through 6 stages: Initialize Application → Load Providers → Boot Services → Resolve Configuration → Start Application → .... Application startup begins with Ignitor.createApp() which loads the container and environment variables. Service providers are then loaded and booted in sequence, registering bindings and initializing modules. For web mode, the HTTP server starts and handles requests through the router. For console mode, the Ace kernel processes CLI commands. Throughout execution, the container resolves dependencies and the configuration system provides typed settings. This pipeline design reflects a complex multi-stage processing system.

What technologies does core use?

The core stack includes @adonisjs/ace (Powers the CLI system with command parsing, argument validation, help generation, and command registration), @adonisjs/application (Core application container and lifecycle management including service providers, IoC container, and environment handling), @adonisjs/http-server (HTTP server implementation with routing, middleware support, request/response handling for web applications), @adonisjs/bodyparser (Request body parsing middleware for JSON, form data, and multipart content in HTTP requests), @boringnode/encryption (Encryption services with multiple drivers (AES-256-CBC, AES-256-GCM, ChaCha20-Poly1305) for data security), youch (Pretty-prints error stack traces with syntax highlighting for better developer experience during debugging), and 1 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does core have?

core exhibits 2 data pools (IoC Container, Application State), 2 feedback loops, 3 control points, 2 delays. The feedback loops handle recursive and retry. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does core use?

4 design patterns detected: Service Provider Pattern, Factory Pattern, Command Pattern, Module Federation.

Analyzed on April 20, 2026 by CodeSea. Written by .