Module lifecycle
Modules in Zumito Framework expose lifecycle hooks that allow you to execute code at specific moments during the bot’s initialization.
Dependency declaration
Section titled “Dependency declaration”Modules can declare dependencies on other modules using static properties. The framework resolves these dependencies and loads modules in the correct order using topological sorting (dependencies first).
moduleName
Section titled “moduleName”Each module can declare its own name, which is used for dependency resolution:
import { Module } from 'zumito-framework';
export class MyModule extends Module { static moduleName = 'my-module';}If moduleName is not declared, the folder name is used as the module name.
dependencies
Section titled “dependencies”Declare required dependencies — modules that must be loaded before this one:
import { Module } from 'zumito-framework';
export class MyModule extends Module { static dependencies = ['logger-module', 'admin-module'] as const;}If a required dependency is not found, the module will not be loaded and an error is logged.
optionalDependencies
Section titled “optionalDependencies”Declare optional dependencies — modules that should be loaded first if present, but will not prevent loading if absent:
import { Module } from 'zumito-framework';
export class MyModule extends Module { static optionalDependencies = ['sentry'] as const;}Legacy requeriments.modules
Section titled “Legacy requeriments.modules”The legacy requeriments.modules property is still supported and is merged with the dependencies array:
export class MyModule extends Module { static requeriments = { modules: ['admin-module'], services: [], custom: [], };}Circular dependencies
Section titled “Circular dependencies”Circular dependencies are detected and reported as errors. The affected modules are skipped during loading:
[📦❌] Circular dependency detected involving: ModuleA, ModuleBinitialize()
Section titled “initialize()”This method is called automatically when the module is loaded. It handles:
- Loading commands from the
commands/folder - Registering events from the
events/folder - Loading translations from the
translations/folder - Registering routes from the
routes/folder
You can override it if you need custom initialization logic, but make sure to call super.initialize():
import { Module } from 'zumito-framework';
export class MyModule extends Module {
async initialize() { await super.initialize(); // Custom initialization code }
}onAllReady()
Section titled “onAllReady()”This hook is called after the entire framework is ready — Discord client connected, all modules loaded, slash commands refreshed, and API server started. It is the ideal place for code that depends on the bot being fully operational.
import { Module } from 'zumito-framework';
export class MyModule extends Module {
async onAllReady() { // Bot is fully ready console.log(`Logged in as ${this.framework.client.user?.tag}`); }
}Framework ready event
Section titled “Framework ready event”As an alternative, you can listen to the ready event emitted by the framework emitter. This is useful when you want to react from an event class without touching the module class:
import { FrameworkEvent } from 'zumito-framework';
export class OnFrameworkReady extends FrameworkEvent {
source = 'framework'; once = true;
async execute(): Promise<void> { console.log('Framework is ready!'); }
}Execution order
Section titled “Execution order”- Discord client connects and emits
ready - All module classes are loaded and their dependencies are resolved
- Modules are topologically sorted (dependencies first)
- Each module is instantiated in sorted order
- Each module’s
initialize()is called in sorted order - Slash commands are refreshed
- API server starts
- Framework
readyevent is emitted - Each module’s
onAllReady()is called - User callback (configured in
zumito.config.ts) is executed