Every pluggable component in Helix — schedulers, allocators, filesystems, drivers — is a module. The ModuleTrait v2 is the recommended API for new modules, providing lifecycle management, event handling, health monitoring, and state persistence for hot-reload.
pub trait ModuleTrait : Send + Sync {
fn info ( & self ) -> ModuleInfo ; // REQUIRED
fn init ( & mut self , ctx : & Context ) -> Result < ( ) , ModuleError > ; // REQUIRED
fn start ( & mut self ) -> Result < ( ) , ModuleError > ; // REQUIRED
fn stop ( & mut self ) -> Result < ( ) , ModuleError > ; // REQUIRED
// Optional — override for custom behavior
fn handle_event ( & mut self , _event : & Event ) -> EventResponse {
fn handle_request ( & mut self , _request : & Request ) -> Result < Response , ModuleError > {
Ok ( Response :: err ( "Not implemented" ) )
fn is_healthy ( & self ) -> bool { true }
fn save_state ( & self ) -> Option < Vec < u8 >> { None }
fn restore_state ( & mut self , _state : & [ u8 ] ) -> Result < ( ) , ModuleError > { Ok ( ( ) ) }
Index ModuleTrait info init start stop handle_event handle_request is_healthy save_state restore_state
Module metadata is declared with a const builder pattern. This means module info is computed at compile time — no runtime overhead.
pub version : ModuleVersion ,
pub description : & 'static str ,
pub author : & 'static str ,
pub license : & 'static str ,
pub dependencies : & 'static [ & 'static str ] ,
pub provides : & 'static [ & 'static str ] ,
// Const builder — all computed at compile time
pub const fn new ( name : & 'static str ) -> Self ;
pub const fn version ( self , major : u16 , minor : u16 , patch : u16 ) -> Self ;
pub const fn description ( self , desc : & 'static str ) -> Self ;
pub const fn author ( self , author : & 'static str ) -> Self ;
pub const fn flags ( self , flags : ModuleFlags ) -> Self ;
pub const fn dependencies ( self , deps : & 'static [ & 'static str ] ) -> Self ;
pub const fn provides ( self , caps : & 'static [ & 'static str ] ) -> Self ;
Index ModuleInfo ModuleInfo
Flags control module behavior and capabilities. Combine them with bitwise OR. When selecting modules for your profile, these flags determine how the module integrates with the kernel.
Flag Bit Description ESSENTIAL1 << 0Cannot be unloaded — kernel panics if it fails HOT_RELOADABLE1 << 1Supports live replacement without restarting USERSPACE1 << 2Runs in user ring (ring 3) DRIVER1 << 3Hardware driver module FILESYSTEM1 << 4Filesystem implementation SCHEDULER1 << 5Scheduler implementation ALLOCATOR1 << 6Memory allocator module SECURITY1 << 7Security policy module EXPERIMENTAL1 << 8Unstable — testing only
Modules receive events from the kernel and can handle requests from other modules. This is the primary communication mechanism between modules.
Tick { timestamp_ns : u64 } ,
MemoryPressure { level : MemoryPressureLevel } ,
CpuHotplug { cpu_id : u32 , online : bool } ,
Custom { name : String , data : Vec < u8 > } ,
pub enum EventResponse { Handled , Ignored , Error ( String ) }
pub source : & 'static str ,
pub request_type : String ,
pub error : Option < String > ,
pub fn ok ( payload : Vec < u8 > ) -> Self ;
pub fn ok_empty ( ) -> Self ;
pub fn err ( message : impl Into < String > ) -> Self ;
Index Event EventResponse Request Response Response ok ok_empty err
When configuring your kernel profile, you select modules in the [modules] section of helix.toml:
profiles/my-kernel/helix.toml # Static modules — linked into the kernel binary at build time
static = ["helix-scheduler-round-robin"]
# Dynamic modules — loaded at runtime (requires dynamic loader)
Category Interface Current Implementations Scheduler helix.schedulerhelix-scheduler-round-robinAllocator helix.allocatorBuilt-in bump + slab allocators Filesystem helix.filesystemHelixFS (built-in) Block Device helix.block_devicePlanned Network helix.networkPlanned Security helix.securityPlanned GPU Driver helix.gpuMagma (planned)
Modules that provide the same interface can be discovered at runtime through the interface registry:
modules/src/interfaces.rs
// Standard interface names
pub const SCHEDULER : & str = "helix.scheduler" ;
pub const ALLOCATOR : & str = "helix.allocator" ;
pub const FILESYSTEM : & str = "helix.filesystem" ;
pub const BLOCK_DEVICE : & str = "helix.block_device" ;
pub const NETWORK : & str = "helix.network" ;
pub const SECURITY : & str = "helix.security" ;
// Discover modules implementing an interface
let schedulers = interface_registry ( ) . get_implementors ( "helix.scheduler" ) ;
let primary = interface_registry ( ) . get_primary ( "helix.scheduler" ) ;
Index interfaces SCHEDULER ALLOCATOR FILESYSTEM BLOCK_DEVICE NETWORK SECURITY
Here's a full, working module that implements a custom scheduler:
modules_impl/my_scheduler/src/lib.rs
use helix_modules :: v2 :: * ;
use helix_modules :: { ModuleError , ModuleFlags } ;
impl ModuleTrait for MyScheduler {
fn info ( & self ) -> ModuleInfo {
ModuleInfo :: new ( "my-scheduler" )
. description ( "Custom round-robin scheduler" )
. flags ( ModuleFlags :: SCHEDULER | ModuleFlags :: HOT_RELOADABLE )
. dependencies ( & [ "helix-execution" ] )
. provides ( & [ "scheduler" , "cpu.scheduling" ] )
fn init ( & mut self , ctx : & Context ) -> Result < ( ) , ModuleError > {
let _time_slice = ctx . config_or ( "time_slice_ms" , "10" ) ;
fn start ( & mut self ) -> Result < ( ) , ModuleError > { Ok ( ( ) ) }
fn stop ( & mut self ) -> Result < ( ) , ModuleError > { Ok ( ( ) ) }
fn handle_event ( & mut self , event : & Event ) -> EventResponse {
_ => EventResponse :: Ignored ,
fn is_healthy ( & self ) -> bool { self . initialized }
Index MyScheduler MyScheduler info init start stop handle_event is_healthy
For the full module system documentation — registry, dependency resolution, interface system, and macros — see the Module System docs page.