What is EventEmitter in Node.js?
Learn how Node.js EventEmitter implements the observer pattern, .on()/.emit()/.once() usage, special error events, and real-world code examples.
Expected Interview Answer
EventEmitter is a core Node.js class that implements the observer pattern, letting objects emit named events and other code subscribe listener functions that run whenever that event fires, forming the backbone of many built-in and custom async APIs.
You create an emitter by extending or instantiating events.EventEmitter, register handlers with .on(eventName, listener), and trigger them with .emit(eventName, ...args). Many core Node APIs are EventEmitters under the hood — HTTP servers emit 'request', streams emit 'data'/'end'/'error', and process emits 'exit'/'uncaughtException'. Listeners run synchronously in registration order when emit() is called, and .once() registers a listener that auto-removes itself after firing once. A key gotcha: EventEmitter has a default max listener limit (10) per event to help catch memory leaks from accidental repeated .on() calls, configurable via setMaxListeners(). Unlike Promises, EventEmitter naturally supports multiple emissions over time, making it ideal for recurring events rather than one-off async results.
- Implements the observer/pub-sub pattern natively
- Decouples the event source from its handlers
- Powers many core Node APIs (streams, HTTP, process)
- Supports multiple listeners per event
- Built-in leak detection via max listener warnings
AI Mentor Explanation
EventEmitter is like a stadium's PA announcer who calls out 'Wicket!' and lets anyone who signed up — the scoreboard operator, the replay team, the commentary box — react independently the moment it's announced. New spectators can subscribe to the announcement at any time, and the announcer doesn't need to know who's listening or how many people react.
EventEmitter pub-sub flow
Emitter
- emit('eventName', data)
Listener A
- Registered via .on()
- Runs on every emit
Listener B
- Registered via .once()
- Runs only on first emit
Step-by-Step Explanation
Step 1
Import EventEmitter
const { EventEmitter } = require('events').
Step 2
Create or extend an emitter
Instantiate directly or extend EventEmitter in a custom class.
Step 3
Register listeners
Use .on(eventName, handler) for repeated events or .once() for a single fire.
Step 4
Emit the event
Call .emit(eventName, ...args) to synchronously invoke all registered listeners.
Step 5
Handle errors specially
The 'error' event has special behavior — with no listener, it throws and can crash the process.
Step 6
Clean up listeners
Use .removeListener() or .off() to avoid memory leaks from stale subscriptions.
What Interviewer Expects
- Explains EventEmitter implements the observer/pub-sub pattern
- Knows .on(), .emit(), and .once() usage
- Mentions core APIs (streams, HTTP, process) built on EventEmitter
- Understands listeners run synchronously in registration order
- Knows about the default max listener warning and setMaxListeners()
Common Mistakes
- Emitting an 'error' event with no listener, crashing the process
- Not removing listeners, causing memory leaks over time
- Assuming emit() runs listeners asynchronously
- Confusing EventEmitter with Promises for one-off async results
Best Answer (HR Friendly)
“EventEmitter lets different parts of a Node.js application react to something happening — like a file finishing upload or a new connection arriving — without being tightly connected to each other. One part announces the event, and any number of other parts can listen and respond independently.”
Code Example
const { EventEmitter } = require('events');
class OrderService extends EventEmitter {
placeOrder(order) {
// ...save order logic
this.emit('orderPlaced', order);
}
}
const orders = new OrderService();
orders.on('orderPlaced', (order) => console.log('Send confirmation email for', order.id));
orders.on('orderPlaced', (order) => console.log('Update inventory for', order.id));
orders.placeOrder({ id: 101 });
// Output:
// Send confirmation email for 101
// Update inventory for 101Follow-up Questions
- What's the difference between .on() and .once() on an EventEmitter?
- What happens if you emit an 'error' event with no listener attached?
- How does EventEmitter relate to Node's core streams API?
- What is the default max listeners limit and why does it exist?
- How would you remove a specific listener from an emitter?
MCQ Practice
1. What pattern does EventEmitter implement?
EventEmitter implements the observer (pub-sub) pattern, letting listeners subscribe to named events.
2. What happens if an 'error' event is emitted with no listeners registered?
The 'error' event is special — with no listener, Node throws the error, potentially crashing the process.
3. What does .once() do differently from .on()?
.once() registers a listener that automatically unregisters itself after being invoked a single time.
Flash Cards
What is EventEmitter? — A core Node.js class implementing the observer pattern for emitting and listening to named events.
How do you fire an event? — Call emitter.emit('eventName', ...args) to synchronously invoke all registered listeners.
What's special about the 'error' event? — If emitted with no listener attached, Node throws it, which can crash the process.
Name a core Node API built on EventEmitter. — Streams (data/end/error events) or HTTP servers (request event).