The shape of a plugin
A plugin is an object with optional lifecycle hooks. Unbound callsstart when the plugin is enabled and stop when it’s disabled.
Set up everything the plugin does (patches, listeners, subscriptions) in start, and tear all of it down in stop.
Whatever you create in
start, undo in stop. A disabled plugin should leave nothing running. Leftover patches and listeners are the most common source of bugs after a plugin is disabled.How plugins are loaded
Unbound loads and evaluates every installed plugin’s bundle at startup, whether or not the plugin is enabled. For a disabled plugin, Unbound never callsstart, but the bundle’s top-level code still runs.
This means anything at the top level of your bundle runs for every user on every launch, even when your plugin is turned off.
Writing a fast plugin
Two techniques keep a plugin’s startup cost near zero until it’s enabled and used.Defer module lookups with lazy
Pass the
{ lazy: true } search option to top-level Metro lookups. The search then runs the first time you access the result (inside start, or later inside a handler) instead of at import.Split heavy work behind a dynamic import
Keep your bundle’s entry point small. Move code that pulls in many modules into separate files, and
import() those files inside start. That code then loads only when the plugin runs.Where to go next
Manifest
The metadata every addon ships and how it’s validated.
Patcher
Intercept and modify any function with the patcher.
Patching Components
Change what Discord’s components render.
Flux Stores
React to Discord’s internal events and stores.
Debugging
Tools for developing and inspecting your plugin.