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:

MethodWhenDo here
configure(options?: Map<string, unknown>)on instance creationread/validate your options
initialize()deferred setupfetch remotes, prepare state
startup()after all plugins are configuredthe real work — register resources, wire IPC, register a widget bundle
shutdown()app close / unloadtear down
MethodPurpose
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:

FieldTypePurpose
namestringhuman name of the plugin
packageNamestringthe package (@teamhud/…)
packageClassstringthe exported class name
versionstringplugin version

Common optional fields:

FieldTypePurpose
descriptionstringone-line summary
author / authorEmailstringattribution
dependenciesstring[]other plugins this one requires
providesstring[]named resources exposed to other plugins
resourcesIPluginResource[]togglable units (a widget is one): { name, kind?, displayName?, canDisable? }
optionsIPluginOption[]configurable options (see below)
tagsRecord<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.