Introduction
TheKernel class extends the base Ace kernel from @adonisjs/ace and adds AdonisJS-specific functionality like:
- Integration with the IoC container for dependency injection
- Access to the application instance
- Custom command loaders
- Global flags and event listeners
- Application lifecycle management
Kernel Location
The Ace kernel is typically created in your application’s console entry point:createAceKernel function from @adonisjs/core/ace.
Creating the Kernel
The kernel is created using thecreateAceKernel helper function:
modules/ace/create_kernel.ts:34
Kernel Configuration
ThecreateAceKernel function automatically:
- Creates a new Kernel instance with the application
- Sets the binary name (defaults to
node ace) - Registers command loaders
- Defines global flags
- Sets up event listeners
Command Registration
The kernel supports multiple ways to register commands:RC File Commands
Commands listed in the.adonisrc.ts file are automatically loaded:
modules/ace/create_kernel.ts:42-46
File System Loader
Commands in thecommands/ directory are automatically discovered using the FsLoader:
modules/ace/create_kernel.ts:53-64
The file system loader optimizes performance by only scanning for commands when necessary. If you’re running a specific command that’s already been registered via the RC file, it skips the file system scan.
Manual Registration
You can manually register commands on the kernel:Global Flags
The kernel defines global flags that work with all commands:—ansi / —no-ansi
Force enable or disable colorful output:modules/ace/create_kernel.ts:69-73
The kernel listens for this flag and switches the UI mode:
modules/ace/create_kernel.ts:83-91
—help
Display help information for any command:modules/ace/create_kernel.ts:75-78
When the help flag is used, the kernel displays the help command and short-circuits execution:
modules/ace/create_kernel.ts:96-101
Kernel Properties
app
The AdonisJS application instance:modules/ace/kernel.ts:33
Commands have access to this via this.app in BaseCommand.
ui
UI primitives for rendering output:prompt
Prompt utilities for user interaction:info
Metadata about the CLI:modules/ace/create_kernel.ts:36
Command Execution
The kernel handles command execution through several steps:1. Command Instantiation
When a command is executed, the kernel uses the application’s container to instantiate it:modules/ace/kernel.ts:34-40
This enables full dependency injection support in commands.
2. Command Execution
Theexec() method on the command runs through the lifecycle:
modules/ace/commands.ts:105-139
3. Error Handling
Errors during command execution are handled by the kernel’s error handler, unless the command’scompleted() hook returns true to suppress default error reporting.
Running Commands Programmatically
You can execute commands programmatically using the kernel:Execute a Command
Handle Command Output
handle() method parses and executes the command array.
Main Command Tracking
The kernel tracks the “main” command (the one directly invoked by the user) vs. sub-commands (commands executed by other commands):modules/ace/commands.ts:156-160
This prevents sub-commands from terminating the application prematurely.
Custom Kernel
You can extend the Kernel class to add custom functionality:Kernel Events
The kernel emits events that you can listen to:Flag Events
Emitted when a global flag is used:Shortcircuit
Stop command execution and return immediately:modules/ace/create_kernel.ts:100
Tracing Channels
Ace supports tracing channels for monitoring command execution:Best Practices
Use the default kernel configuration
Use the default kernel configuration
Unless you have specific needs, use the
createAceKernel helper function instead of manually creating the kernel. It handles all the standard configuration.Register commands in .adonisrc.ts
Register commands in .adonisrc.ts
For better performance, register frequently-used commands in
.adonisrc.ts instead of relying solely on file system scanning.Use kernel.exec() for sub-commands
Use kernel.exec() for sub-commands
When executing commands from within other commands, use
kernel.exec() instead of manually instantiating command classes:Leverage dependency injection
Leverage dependency injection
The kernel’s integration with the IoC container means you can inject dependencies into command lifecycle methods: