Subscribe to Events — Node's Pub/Sub Pattern
EventEmitter
EventEmitter is the base class behind HTTP, streams, and the bulk of Node's async APIs.
What you'll learn
- Emit and listen to custom events
- Use `once` for single-fire
- Convert events to promises
EventEmitter is the base class for Node’s pub/sub pattern. HTTP
servers, streams, child processes — they all extend it.
A Custom Emitter
import { EventEmitter } from "node:events";
const bus = new EventEmitter();
bus.on("user-created", (user) => {
console.log("welcome,", user.name);
});
bus.emit("user-created", { id: 1, name: "Ada" });
// welcome, Ada on(event, fn)— subscribeemit(event, ...args)— fireoff(event, fn)— unsubscribe
once
Listen for the next occurrence, then auto-remove:
bus.once("ready", () => console.log("first time only"));
bus.emit("ready"); // logs
bus.emit("ready"); // nothing — listener already removed Multiple Listeners
You can subscribe many functions to one event:
bus.on("order", (o) => savePaymentTrail(o));
bus.on("order", (o) => sendEmail(o));
bus.on("order", (o) => updateDashboard(o));
bus.emit("order", { id: 42 }); // all three run By default a max of 10 listeners per event triggers a warning. Bump it if needed:
bus.setMaxListeners(100); Events → Promises
To await an event:
import { once } from "node:events";
const [user] = await once(bus, "user-created");
console.log("got", user); once returns a promise that resolves with the event’s arguments
as an array — perfect for “wait for a signal” patterns.
Real-World Use
import { createServer } from "node:http";
const server = createServer();
server.on("request", (req, res) => res.end("hello"));
server.on("listening", () => console.log("up"));
server.on("error", (e) => console.error("boom", e));
server.listen(3000); Every Node API you’ll use has events under the hood.
The process Object →