Introduction
Mitt is a microscopic event emitter library that weighs just 200 bytes gzipped. Created by Jason Miller (author of Preact), it provides a clean publish-subscribe pattern for decoupling components in any JavaScript application — from framework-agnostic UI state to Node.js service internals.
What Mitt Does
- Registers typed event handlers with
on(type, handler)for specific events or*for all events - Emits events with
emit(type, data), invoking all registered handlers synchronously - Removes specific handlers with
off(type, handler)or clears all withall.clear() - Provides full TypeScript generics for type-safe event maps
- Returns a plain object — no class instantiation, no prototype chain, no inheritance
Architecture Overview
Mitt stores handlers in a Map of event-type to handler-array. The emit function iterates the handler array (and the wildcard array) synchronously, invoking each function with the event data. The entire implementation is under 10 lines of functional JavaScript with no closures over mutable state beyond the Map itself. This simplicity makes it auditable, predictable, and impossible to leak memory through complex listener chains.
Self-Hosting & Configuration
- Install via npm — zero dependencies, single file
- Import as ESM (
import mitt from 'mitt') or CommonJS (`require('mitt')``) - Define an event map type for TypeScript:
mitt<{ login: User; logout: void }>() - Use the wildcard handler
emitter.on('*', (type, e) => ...)for logging or debugging all events - Share a single emitter instance across modules via a dedicated file export
Key Features
- 200 bytes gzipped — the smallest full-featured event emitter available
- Type-safe events with TypeScript generics and mapped event types
- Functional design — no classes, no
thisbinding issues, works with any paradigm - Wildcard listener receives all events, useful for middleware and logging patterns
- Over 11,800 GitHub stars with adoption in Preact ecosystem and Vue 3 migration guides
Comparison with Similar Tools
- EventEmitter (Node.js) — built-in but heavier, class-based, and not typed; Mitt is 200 bytes and type-safe
- EventEmitter3 — faster Node-style emitter; Mitt is smaller and functional-first
- nanoevents — similar size philosophy; Mitt has simpler API and wider TypeScript adoption
- RxJS — full reactive streams; Mitt is for simple pub/sub without observable complexity
- EventTarget (DOM) — browser native; Mitt works identically in Node.js and browsers
FAQ
Q: Is Mitt suitable for large applications? A: Yes, for event-bus patterns. It handles thousands of listeners efficiently. For complex event flows with filtering and transformation, consider RxJS instead.
Q: Can I use Mitt as a Vue 3 event bus? A: Yes. Vue 3 removed the built-in event bus ($on/$emit on instances), and the official migration guide recommends Mitt as a replacement.
Q: Does Mitt support once-only listeners?
A: Not built-in, but trivially implemented: register a handler that calls off on itself after first invocation.
Q: Is it safe to emit during handler execution? A: Yes. Mitt iterates a snapshot of the handler array, so adding or removing handlers during emit does not cause missed or double invocations.