event-pubsub
Event Pubsub for Javascript will work in node js or browser
Event-pubsub is a synchronous publish subscribe module for Node and the browser
A small, extensible publish/subscribe library that runs in Node.js and in bundled or unbundled browsers from a single native ESM source.
What the module provides
Event-pubsub is a small, synchronous, extensible publish and subscribe implementation for Node.js plus bundled and unbundled browsers. The README states it works with bundlers and without a bundler, because both paths execute the same native ESM source, and direct browser use needs only a standard import map rather than a build or transpilation step. The current npm and GitHub release is 6.1.1, and the module can be imported in Node.js 22.12 or newer through either import or require, and in a native browser application through an import map. The API exposes five fluent methods: on, once, off, emit, and reset. Dispatch is synchronous and follows registration order, with wildcard subscribers run first. One-shot subscribers are removed before invocation, including during reentrant emits. The module returns the current instance from its public mutators so calls can be chained. It also guards safe event names such as __proto__, constructor, and toString, and it returns isolated list snapshots that cannot mutate the live registry. The README positions the library as a dependency-light primitive for applications that need a predictable event hub, and it notes that all public mutators return the current instance so a builder style of registration reads cleanly in application code. The package also ships a benchmark command that records fixed-count latency samples across eight scenarios, giving anyone comparing dispatch cost a repeatable way to measure median nanoseconds per emit.
Dispatch behavior and wildcard events
The dispatch model is deterministic. Subscriber arrays remain live during an emit, so handlers added in that emit can run, and specifically removed handlers are skipped before their turn. Removing a whole bucket or resetting the registry detaches it from future lookup while an already-active array finishes. Wildcard subscribers, registered with the exact string '*', run before typed subscribers and receive the emitted type as their first argument. The wildcard list entry is exposed at Symbol.for('event-pubsub-all'), and only the literal '*' maps to that internal symbol, so an ordinary string that happens to name the symbol never aliases wildcard removal. The README documents that synchronous handler throws propagate to the publisher, while return values and promises are ignored, so applications must handle asynchronous rejections themselves. Event types must be strings, and on and once validate their handler immediately. The off method defaults its type and handler arguments to wildcard removal, which makes it easy to tear down a whole topic or the entire registry. This careful handling of edge cases, including reentrant dispatch and safe prototype names, is the substance of the project and the reason it ships such a large regression suite. Coverage gates report 100 percent on native V8 executable, block, function, and line totals for both Node and Chrome, which the README presents as the bar the release must clear.
Verification and performance evidence
The README describes a shared, host-neutral test registry of 131 unique checks executed by vanilla-test 2.1.1 in both Node and real Google Chrome. The inventory breaks into Unit (16 cases), Functional (26), Integration (14), Behavioral (12), Regression (43), and Interface (20) suites, all run against one registry. A runtime and CI matrix shows 131 out of 131 passing on Node 22.12.0 and Node 24 across Ubuntu, macOS, and Windows, with Node 24.18.0 and Chrome Stable both reporting 100 percent on native V8 executable, block, function, and line coverage. The release gate also bundles and executes a packed conflicting-dependency consumer with Rollup and runs the tarball directly in Chrome through normal and scoped import maps. On performance, the README reports measured dispatch latency as median nanoseconds per emit, with p25 to p75 whiskers and all samples shown, and it excludes setup, warmup, validation, serialization, file I/O, and CI orchestration from the timing. The benchmark evidence and live test results are published to a GitHub Pages site so the claims can be inspected, and the package resolves its single production validator, strong-type 2.0.0, through a scoped dependency boundary that survives a poisoned root install. A shared test registry of 131 checks runs in both Node and real Google Chrome, so the same inventory guards the module across server and browser runtimes.
Editorial conclusion
The library is written in JavaScript, carries the MIT license, and the metadata records 21 stars with the 6.1.1 release noted in the README.
Community notes