Skip to content

plugin/plugin-lifecycle-events

The lifecycle broadcast every PluginBase makes: obsidian-dev-utils:plugin-loaded when it has finished loading and obsidian-dev-utils:plugin-unloaded when it goes away.

Obsidian gives a plugin no way to learn that ANOTHER plugin was enabled or disabled — there is no such event on app.plugins, and a plugin’s own Events source cannot help a listener that does not yet hold the instance. So the broadcast goes through app.workspace, which is one object every plugin in the vault can reach. Deliberately NOT the globalThis.__obsidianDevUtils bag the rest of the library shares its state through: a listener there needs its own copy of this library, and these events are meant to be consumable by any plugin at all.

The names are past tense because a broadcast states something that has already happened. loaded in particular carries a guarantee: it is triggered only after every API the plugin declares has been published, so a listener may call them immediately.

Both the event names and PluginLifecycleEventPayload are a CROSS-VERSION CONTRACT. Copies of this library at different versions publish and consume them side by side in one vault, so neither may change incompatibly: plain data only, and new payload fields only ever added.

That contract is also PUBLISHED, as of the Plugin API protocol guide: third-party plugins that will never install this library are told to hardcode these two strings and this payload shape. Publishing it added no new constraint — the cross-copy one above already forbade every change an outsider could notice — but it does mean a rename is now doubly unavailable. The obsidian-dev-utils: prefix names the library rather than the subject, which is a wart, and a permanent one: a neutral alias would not retire the old name (already-released plugins emit only it), so it would leave every correct consumer listening for both, forever.

Interface Description
PluginLifecycleEventPayload The payload of PLUGIN_LOADED_EVENT_NAME and PLUGIN_UNLOADED_EVENT_NAME. Plain data by design — no class instances and no types owned by this library — because it crosses between independently bundled copies of it, and between plugins that do not use it at all.
TriggerPluginLifecycleEventParams Parameters for triggerPluginLifecycleEvent.
Function Description
triggerPluginLifecycleEvent Triggers one of the two lifecycle events on the app’s workspace. A thin typed wrapper over Workspace.trigger, which accepts any event name and any arguments, so that the one place a payload is constructed is checked against PluginLifecycleEventPayload.
Type Description
PluginLifecycleEventName The name of either lifecycle event.
Variable Description
PLUGIN_LOADED_EVENT_NAME Triggered once a plugin has finished loading AND published every API it declares, so a listener may call those APIs immediately. Namespaced by the package name rather than by an abbreviation of it: the event is global to the vault and aimed at plugin authors who have never heard of this library, so the prefix has to identify itself.
PLUGIN_UNLOADED_EVENT_NAME Triggered as a plugin unloads — whether the user disabled it, uninstalled it, or Obsidian is shutting down. Its APIs are revoked by the time a listener runs.