Events Best Practices
In-process events stay maintainable with explicit contracts, disciplined cleanup, and clear boundaries between notification and durable messaging.
Search across all documentation pages
In-process events stay maintainable with explicit contracts, disciplined cleanup, and clear boundaries between notification and durable messaging.
EventEmitter, @OnEvent, or socket on handlers.order.paid, not payOrder). Reflects facts that already happened.v2 envelope or new event name). Document migration for subscribers.off, once, or AbortSignal.setMaxListeners without fixing duplicate registration. Warnings indicate leaks.afterEach. Prevent flaky listener accumulation.removeAllListeners only for app-owned buses. Not on shared Node internals recklessly.Promise.allSettled fan-out. One failure must not break others silently.data events on custom emitters.emit/on. See Typed EventEmitter.listenerCount returns to baseline after scoped work. Automated leak regression test.Listeners on global emitters never removed - slow memory growth over days.
Often yes - but isolate errors and prefer queue for heavy or retriable side effects.
More than one per event on global bus per request scope is suspicious - investigate architecture.
Different API surface - same cleanup discipline applies to on('data').
Keep handlers thin; push durable work to BullMQ; module scope providers reduce global singleton misuse.
Avoid - ordering surprises during boot; explicit bootstrap() phase instead.
Many classes emit 'error' - handle or process crashes for unhandled error events on some streams.
Commands are imperative (CreateOrder) - events are facts (order.created). Do not mix semantics.
ADR or docs/events.md table: name, payload schema, producers, consumers, idempotency notes.
Same cleanup on disconnect - see socket.io for transport-specific rules.
OK for domain counters - avoid high-cardinality emit per request without aggregation.
Domain Events vs EventEmitter for queue vs bus decisions.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.
Reviewed by Chris St. John·Last updated Jul 16, 2026