← Back to home

Kwirth Daemons

Daemons are headless backend workers that run continuously inside Kwirth without requiring a user session. Same processing power as plugins — no browser tab needed.

What is a daemon?

A Kwirth daemon is a backend-only extension that runs autonomously alongside the Kwirth core. Unlike plugins, daemons have no frontend component and no WebSocket session — they start when Kwirth starts and keep running regardless of who is connected.

Daemons are ideal for continuous background processing: log filtering, alerting, data forwarding, or any task that should run 24/7 without user interaction.

PluginDaemon
UIYes — React tab in the front endNone — headless
Triggered byUser opening a tabKwirth startup / API call
SessionTied to a WebSocket connectionIndependent, survives reconnects
Use caseInteractive explorationContinuous background processing
ProvidersYesYes
SendersYesYes
StorageYesYes

Available daemons

🚫

Censor

Headless version of the Censor plugin. Watches selected containers, batches log lines, calls an LLM to learn noise regex patterns, and applies them continuously — forwarding only meaningful lines to the configured sender. Runs without any browser tab open.

Available
⚙️

Your Daemon

Any continuous background task: log archival, metric aggregation, business-event correlation, compliance checks. The daemon interface gives you full access to cluster state, providers, senders, and storage.

Build your own

Daemon interface

Every daemon must implement the IDaemon interface from @kwirthmagnify/kwirth-common-back:

daemonId: stringUnique identifier (e.g. "censor")
getDaemonData()Returns static metadata: id, display name, version
startDaemon()Called once at startup — load config, subscribe to providers, begin processing
containsInstance(id)Returns true if the daemon is managing a given instance id
containsAsset(id, ns, pod, c)Returns true if the given container is already tracked by an instance
addObject(cfg, ns, pod, c)Called when a Kubernetes container matching the daemon's scope is discovered
deleteObject(cfg, ns, pod, c)Called when a tracked container is removed from the cluster
processCommand(id, cmd, data?)Handles management commands sent via the Kwirth API (get/set config, start/stop analysis, etc.)

Build your own daemon

A daemon is a single CJS bundle compiled with esbuild. Project layout mirrors the plugin and provider structure:

daemons/my-daemon/
  src/
    back/index.ts     ← implements IDaemon, exports as default
  build.mjs           ← esbuild script (node platform, CJS format)
  package.json        ← includes id, name, version, description

Minimal scaffold:

import { IDaemon, IBackDaemonObject, IDaemonInstanceConfig, BackDaemonData }
    from '@kwirthmagnify/kwirth-common-back'

export class MyDaemon implements IDaemon {
    readonly daemonId = 'my-daemon'

    constructor(private clusterInfo: unknown, private bdo: IBackDaemonObject) {}

    getDaemonData(): BackDaemonData {
        return { id: 'my-daemon' }
    }

    async startDaemon(): Promise {
        this.bdo.logInfo?.('[my-daemon] started')
        // subscribe to providers, load config from storage, etc.
    }

    containsInstance(id: string): boolean { return false }
    containsAsset(id: string, ns: string, pod: string, c: string): boolean { return false }

    async addObject(cfg: IDaemonInstanceConfig, ns: string, pod: string, c: string): Promise {
        // start watching this container
        return true
    }

    async deleteObject(cfg: IDaemonInstanceConfig, ns: string, pod: string, c: string): Promise {
        return true
    }

    async processCommand(instanceId: string, command: string, data?: unknown): Promise {
        return null
    }
}

export default MyDaemon

Register it for local development in kwirth-dev.json:

{
  "daemons": {
    "my-daemon": "../daemons/my-daemon/dist"
  }
}

Kwirth watches dist/back.js and hot-reloads the daemon whenever it changes.

Ready to build a daemon?

Full IDaemon interface reference, lifecycle documentation, and the Censor daemon source are in the Kwirth docs.

Daemon docs → Censor daemon source