Skip to content

Plugin API

A plugin is a TypeScript class that extends BasePlugin (from @mythic/plugins) and runs in the main process. This page is the authoring surface — the methods you implement and the metadata you declare. For a guided build, see Build your first plugin.

Implement the hooks you need; each returns Promise<void> and the framework calls them in this order:

Method When Do here
configure(options?: Map<string, unknown>) on instance creation read/validate your options
initialize() deferred setup fetch remotes, prepare state
startup() after all plugins are configured the real work — register resources, wire IPC, register a widget bundle
shutdown() app close / unload tear down
Method Purpose
onSystemEvent(event: SystemEventsEnum) react to runtime lifecycle events
onPluginEvent(eventName: string, data: unknown) react to events emitted by other plugins

SystemEventsEnum values: PRE_GLOBAL_INITIALIZATION, POST_GLOBAL_INITIALIZATION, PRE_GLOBAL_STARTUP, POST_GLOBAL_STARTUP, PRE_GLOBAL_SHUTDOWN, POST_GLOBAL_SHUTDOWN.

info() returns the plugin’s metadata. Required fields:

Field Type Purpose
name string human name of the plugin
packageName string the package (@teamhud/…)
packageClass string the exported class name
version string plugin version

Common optional fields:

Field Type Purpose
description string one-line summary
author / authorEmail string attribution
dependencies string[] other plugins this one requires
provides string[] named resources exposed to other plugins
resources IPluginResource[] togglable units (a widget is one): { name, kind?, displayName?, canDisable? }
options IPluginOption[] configurable options (see below)
tags Record<string, unknown> freeform metadata (TeamHUD uses e.g. tags.canDisable, tags.isWidget)
trustLevel 'trusted' | 'semi-trusted' | 'untrusted' defaults 'trusted'; 'untrusted' runs the plugin in a worker sandbox

Options (IPluginOption): { name, description?, defaultValue?, type?, environmentVariable?, isSensitive? }. Mark any option holding a credential isSensitive: true so its value is kept out of logs.

The smallest complete plugin — lifecycle only, no widget:

import { BasePlugin } from '@mythic/plugins';
import type { IPluginInfo, SystemEventsEnum } from '@mythic/plugins';
import { Logger } from '@mythic/logging';
export class HelloPlugin extends BasePlugin {
private logger = new Logger(HelloPlugin);
info(): IPluginInfo {
return {
name: 'HelloPlugin',
packageName: '@teamhud/hello',
packageClass: 'HelloPlugin',
version: '0.1.0',
description: 'Minimal hello plugin',
};
}
override async configure(_options?: Map<string, unknown>): Promise<void> {}
override async initialize(): Promise<void> {}
override async startup(): Promise<void> { this.logger.info('Hello from HelloPlugin'); }
override async shutdown(): Promise<void> {}
override async onSystemEvent(_event: SystemEventsEnum): Promise<void> {}
override async onPluginEvent(_eventName: string, _data: unknown): Promise<void> {}
}

A plugin that provides a widget adds a renderer bundle registration in startup() — see Build your first plugin.