Guide

From install to event flow.

The runtime is intentionally small. This page covers the complete mental model; detailed signatures live on the API page.

  1. Install

    npm install event-pubsub

    This installs the current npm release, 6.1.1, on Node.js 22.12 or newer.

  2. Create one event hub per boundary

    import EventPubSub from 'event-pubsub';
    const events = new EventPubSub();

    CommonJS on Node.js 22.12 or newer loads the same source with const EventPubSub = require('event-pubsub');.

  3. Register before publishing

    events.on('message.received', handleMessage);
    events.once('app.ready', warmCache);
  4. Publish synchronously

    events.emit('message.received', message, metadata);
  5. Clean up at the lifecycle boundary

    events.off('message.received', handleMessage);
    events.reset();

Dispatch contract

Predictable order under mutation.

Wildcard first

* subscribers receive (type, ...payload) before typed subscribers receive (...payload).

Live iteration

Subscribers appended to the active array can run in the same emit. Specifically removed handlers are skipped before their turn; removing a whole bucket detaches it from future lookup while an already-active array finishes.

Once before call

One-shot records are removed before invocation, preventing repeat calls during reentrant emits or after a thrown error.

The 6.1.1 package works with a bundler and without one.

Bundlers resolve both package names normally and may use the package's browser entry. Native browsers do not read that field; without a bundler, they execute the same ESM files directly—no build or transpilation step—when this import map appears before the first module script:

<script type="importmap">
{"imports":{"event-pubsub":"./node_modules/event-pubsub/index.js","strong-type":"./node_modules/strong-type/index.js"}}
</script>
<script type="module">import EventPubSub from 'event-pubsub';</script>

Serve the files over HTTP(S), not file://, and expose the mapped node_modules files. When npm nests the validator under event-pubsub, use the scoped conflict map in the README.

If the app uses a strict CSP, authorize the inline import-map and module scripts with an allowed nonce or hash.