Skip to main content

Overview

The EventBus is a simple pub/sub system that enables decoupled communication between plugins.
api.bus.on('todo:added', (data) => {
  console.log('New todo:', data.text);
});

api.bus.emit('todo:added', { text: 'Buy milk' });

Methods

bus.on(event, callback)

Subscribe to an event. Multiple listeners can subscribe to the same event.
api.bus.on('theme:changed', (data) => {
  document.body.style.background = data.color;
});
ParameterTypeDescription
eventstringEvent name
callbackfunctionHandler called with event data

bus.off(event, callback)

Unsubscribe from an event. Must pass the same function reference used in on().
function handler(data) { /* ... */ }

api.bus.on('my-event', handler);
// later:
api.bus.off('my-event', handler);

bus.once(event, callback)

Subscribe to an event, but the listener is automatically removed after the first emission.
api.bus.once('board:ready', (data) => {
  console.log('Board is ready, only fires once');
});
ParameterTypeDescription
eventstringEvent name
callbackfunctionHandler called once with event data, then removed

bus.emit(event, data)

Publish an event to all subscribers. Errors in listeners are caught and logged without interrupting other listeners.
api.bus.emit('todo:added', { text: 'Buy milk', done: false });
ParameterTypeDescription
eventstringEvent name
dataanyPayload passed to subscribers

bus.removeAll([event])

Remove all listeners for a specific event, or all events if no event name is given.
// Remove all listeners for a specific event
api.bus.removeAll('todo:added');

// Remove ALL listeners across all events
api.bus.removeAll();
ParameterTypeDescription
eventstring(Optional) Event name. If omitted, clears everything.
removeAll() with no arguments is a nuclear option. Use with care — it removes listeners from every plugin, not just yours.

Naming Convention

Use namespace:action to avoid collisions between plugins:
✅ Good❌ Bad
todo:addedadded
kanban:card:movedmove
theme:changedchange
sticky-note:creatednew

Example: Cross-Plugin Communication

// === todo-list/plugin.js ===
export function setup(api) {
  const todos = [];

  function addTodo(text) {
    todos.push({ text, done: false });
    api.bus.emit('todo:added', { text, count: todos.length });
  }
}

// === stats/plugin.js ===
export function setup(api) {
  let count = 0;

  api.bus.on('todo:added', (data) => {
    count = data.count;
    renderStats();
  });
}
Plugins should never directly import or reference each other. Always use the event bus for communication.