EventEmitter3

A blazing-fast, drop-in EventEmitter for Node.js and browsers

Library
npm
v5.0.4
3,537 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
45 /100 Fair
Development Activity 0
Maintenance 20
Community 60
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
78 /100 Good
Architecture 75
Code Quality 85
Innovation 85
Learning Curve 65

EventEmitter3 is a high-performance, standalone EventEmitter implementation designed to be a drop-in replacement for Node.js’s built-in events module. It strips away rarely-used features like domains, the newListener/removeListener meta-events, and setMaxListeners in favor of raw speed, while adding contextual this binding for listeners so consumers don’t need fn.bind.

Written in ECMAScript 3 for maximum compatibility, it runs unmodified in the oldest browsers and Node versions, making it a popular low-level dependency for real-time libraries, game engines, and UI frameworks such as PixiJS and Socket.IO/Primus.

What You Get

  • A Node.js-compatible EventEmitter API (on, once, emit, off, listeners, eventNames) usable in both Node and browsers
  • Contextual listener binding via a context argument, avoiding the overhead of Function.prototype.bind
  • An ES3-compatible implementation that runs in legacy browsers and old Node versions without polyfills
  • TypeScript type definitions (index.d.ts) plus both CommonJS (index.js) and native ESM (index.mjs) builds

Common Use Cases

  • Powering internal pub/sub in real-time transport libraries like Socket.IO and Primus
  • Driving event systems in rendering/game engines such as PixiJS
  • Providing lightweight state-change notifications inside UI component libraries
  • Replacing Node’s built-in EventEmitter in performance-sensitive server code

Under The Hood

Architecture — EventEmitter3 is a single ~330-line module (index.js) built around three small constructors: Events (a null-prototype map of event name to listener), EE (a wrapper holding a listener function, its bound context, and a once flag), and the public EventEmitter class that owns an Events instance. To sidestep prototype-pollution and shadowing of built-in Object.prototype members, event storage uses Object.create(null) where available, falling back to a ~ name-prefixing trick on engines without it (detected once at module load, not per-call). emit special-cases 0-6 argument counts with unrolled function calls before falling back to Function.prototype.apply for more, trading code size for call-path speed.

Tech Stack — Zero runtime dependencies; published as plain ECMAScript 3 so it works unmodified in ancient browsers and Node releases. The package.json exports map serves index.d.ts (types), index.mjs (ESM), and index.js (CJs) from a single source tree. Rollup + @rollup/plugin-terser produce a minified UMD bundle for the dist/ CDN build, generated only at prepublishOnly time (not committed to the repo).

Code Quality — Tests live in test/test.js (CJS, run via Mocha) and a parallel test/test.mjs (ESM entry point), using the assume assertion library; c8 collects V8-native coverage with both lcov and text reporters wired into npm test. The source carries consistent JSDoc annotations on every method (@param, @returns, @private), and naming is terse but consistent with the Node.js events module it mirrors, which keeps the diff between the two APIs easy to reason about.

API Design — The public surface deliberately mirrors Node’s built-in EventEmitter (on, once, emit, removeListener, removeAllListeners, listeners, eventNames, listenerCount) so it’s usable as a near drop-in replacement with no relearning cost. Its one notable extension — passing a context object as an extra argument to on/once/removeListener — removes the common need for fn.bind(this) at call sites, a small but genuinely ergonomic addition documented directly in the README with runnable examples.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers