Docs
Developer Documentation

Utilities

The cross-cutting helpers every extension shares: config files, structured logging, request events, and payload signing.

These helpers are available to every building block through this.kora.

Config files

Extensions can keep their own config, namespaced under the extension so it never collides with Kora's. Register it in onStartup() by passing your extension name, a file name, and the default shape.

onStartup() {
    this.kora.config.initialize(this.getName(), "settings", {
        SETTINGS: {
            ENABLED: true,
            MODE: this.kora.config.validator.enum("basic", "advanced"),
            LIMITS: { MAX: 10 }
        }
    });
}

This creates config/my-extension/settings.json from the defaults on first run. Read it anywhere with this.kora.config.get(this.extension, "settings").SETTINGS. Config files are self-healing: missing keys are added back with their defaults and unreadable files are rebuilt, so users cannot break your extension by editing them. Use this.kora.config.validator.enum(...) for a value that must be one of a fixed set (the first entry is the default).

Logging

Log through this.kora.console so your output matches Kora's format and respects the user's console settings. Pick a level from this.kora.console.levels:

this.kora.console.log(this.kora.console.levels.info, "Something happened.");
LevelUse it for
infogeneral information
successan operation completed
warningsomething recoverable that deserves attention
errora failure
debugdetail shown only when KORA.CONSOLE.DEBUG is on
startupboot-time messages
clioutput from a CLI command

Request events

Kora exposes a shared Node EventEmitter at this.kora.events. Subscribe to it in onStartup() to react to things happening across the whole instance, then unsubscribe in onShutdown() if your listener holds onto anything.

The built-in api.request event fires once for every request to a route, after the response has been fully sent, whatever the outcome (success, an auth failure, a rate limit, or a handler error). It is a convenient hook for analytics, auditing, or usage tracking.

onStartup() {
    this.kora.events.on("api.request", event => {
        this.kora.console.log(this.kora.console.levels.debug, `${event.method} ${event.path} => ${event.status} (${event.duration}ms)`);
    });
}

The event payload is:

FieldDescription
methodThe HTTP method (GET, POST, ...).
pathThe route's path.
statusThe HTTP status code that was sent.
durationHow long the request took, in milliseconds.
keyThe name of the API key used, or null for public routes.
ipThe caller's IP address, or null if it could not be determined.
agentThe request's User-Agent header, or null.

Signing payloads

this.kora.backend.signature creates and checks HMAC signatures: useful for signing an outgoing webhook or verifying that an incoming request really came from a trusted source. Strings are signed as-is; objects are hashed with stably sorted keys, so the same data always produces the same signature regardless of key order.

const signature = this.kora.backend.signature.sign(payload, secret);
const trusted = this.kora.backend.signature.verify(payload, secret, signature);
  • sign(data, secret, algorithm = "sha256") returns a hex signature for data.
  • verify(data, secret, signature, algorithm = "sha256") returns true only when the signature matches, using a constant‑time comparison that is safe against timing attacks.

On this page