cozyevent
v1.4.2
Published
World's fastest, Lightweight Async/Sync Event Emitter, also for React
Maintainers
Readme

CozyEvent — World's fastest, Lightweight Event Emitter also for React
A lightweight ; only 341 Bytes (bundle size), might be the worlds fastest, microtask-based asynchronous and synchronous event emitter for JavaScript/TypeScript. Also for REACT! Check the benchmark results below!
Whats COZY stands for;
COZY stands for Compact, On-point, Zero-overhead, Yet-powerful.
A fine-tailored ecosystem of TypeScript libraries designed for your everyday needs—lightweight, efficient, and built to get the job done. No bloat, just pure performance. 🚀
Change log
- v.1.4.0: React Support; CozyEvent has now react support! (Special thanks to jeangq24 )
- v.1.2.0: Performance improvement; 22x faster than v.1.1.0 (see the benchmark below)
- v1.1.0: Performance improvement; 4x faster than version v1.0 (see the benchmark bellow)
Features
- Supports both synchronous and asynchronous (microtask-based) event emission.
- Allows multiple listeners per event.
- Provides once event handling.
- Enables removal of specific or all event listeners.
- Designed for performance with a minimal footprint.
Installation
You can install CozyEvent via npm or yarn:
Light version - non react (only 341 Bytes)
npm install cozyevent@latest-lightor
yarn add cozyevent@latest-lightOr With React supported version
npm install cozyeventor
yarn add cozyeventUsage
Importing CozyEvent
ESModule
import { CozyEvent } from 'cozyevent';CommonJS
const { CozyEvent } = require('cozyevent');Creating an Event Emitter
const eventEmitter = new CozyEvent();Registering Event Handlers
on(event: string, handler: EventHandler): void
Registers an event listener that triggers every time the event is emitted.
eventEmitter.on('message', (msg) => {
console.log(`Received: ${msg}`);
});once(event: string, handler: EventHandler): void
Registers an event listener that triggers only once.
eventEmitter.once('init', () => {
console.log('Initialization complete!');
});Emitting Events
emit(event: string, ...args: any[]): void
Emits a sync event.
eventEmitter.emit('message', 'Hello, World!');emitAsync(event: string, ...args: any[]): void
Emits an async event emission using microtasks.
eventEmitter.emitAsync('data', { id: 1, name: 'John Doe' });Removing Event Listeners
off(event: string, handler: EventHandler): void
Removes a specific event listener.
const handler = (msg) => console.log(msg);
eventEmitter.on('chat', handler);
eventEmitter.off('chat', handler);removeAllListeners(event?: string): void
Removes all listeners for a specific event or all events if no event is specified. This method replaces the previous destroy method, as it now handles the same functionality.
eventEmitter.removeAllListeners('chat');Extending CozyEvent
You can extend CozyEvent in your own class to create a custom event-driven system:
class SomeClass extends CozyEvent {
doSomething() {
console.log('Doing something...');
this.emit('done', 'Task completed');
}
}
const instance = new SomeClass();
instance.on('done', (message) => {
console.log(`Received: ${message}`);
});
instance.doSomething();Destroying the Event Emitter (Deprecated)
destroy(): void
Deprecated: This method has been replaced by
removeAllListeners(). UseremoveAllListeners()to achieve the same functionality.
// Deprecated
eventEmitter.destroy();
// Recommended
eventEmitter.removeAllListeners();CozyEvent React Integration
CozyEvent provides seamless React integration through:
CozyEventProvider(Context Provider)useCozyEvent(Custom Hook)- Centralized Instance Registry
This allows declarative event management in React applications, supporting multiple instances and automatic event cleanup.
Installation
npm install cozyeventor
yarn add cozyeventComponents & Hooks
CozyEventProvider
A React context provider that supplies a CozyEvent instance to child components.
Props:
instance?: CustomCozyEventinstance (defaults to global instance).children: Child components with event access.id?: Identifier for managing multiple instances (default:'default').
Example:
import { CozyEventProvider } from 'cozyevent';
const App = () => (
<CozyEventProvider>
<MyComponent />
</CozyEventProvider>
);useCozyEvent
A hook for subscribing to events from the nearest CozyEventProvider.
Parameters:
eventName: Event name (required).callback: Function executed when the event is emitted (required).options?:namespace?: Scope event subscription.id?: Target a specificCozyEventProvider.
Returns:
CozyEventinstance.
Example:
import { useCozyEvent } from 'cozyevent';
const EventListener = () => {
useCozyEvent('message', (data) => {
console.log('Received:', data);
});
return <div>Listening...</div>;
};Centralized Instance Registry
Manages multiple CozyEvent instances globally.
registerCozyEventInstance(id: string, instance: CozyEvent)
Registers an instance.
Note: You don't need to manually register the instance before creating the
CozyEventProvider. The provider will automatically register the instance with the givenid.
import { registerCozyEventInstance, CozyEvent } from 'cozyevent';
const emitter = new CozyEvent();
registerCozyEventInstance('custom', emitter);getCozyEventInstanceById(id: string): CozyEvent | undefined
Retrieves an instance.
import { getCozyEventInstanceById } from 'cozyevent';
const emitter = getCozyEventInstanceById('custom');
emitter?.emit('event', 'Hello!');Usage Examples
Basic Usage
import React from 'react';
import { CozyEventProvider, useCozyEvent } from 'cozyevent';
const EventEmitter = () => {
const emitEvent = () => {
getCozyEventInstanceById('default')?.emit('test-event', 'Hello!');
};
return <button onClick={emitEvent}>Emit Event</button>;
};
const EventListener = () => {
useCozyEvent('test-event', (message) => alert(message));
return <div>Listening for events...</div>;
};
const App = () => (
<CozyEventProvider>
<EventEmitter />
<EventListener />
</CozyEventProvider>
);
export default App;Using Namespaces
useCozyEvent('user-login', (data) => console.log('Logged in:', data), {
namespace: 'auth',
});Multiple Instances
const App = () => (
<>
<CozyEventProvider id="auth">
<AuthModule />
</CozyEventProvider>
<CozyEventProvider id="notifications">
<NotificationModule />
</CozyEventProvider>
</>
);const AuthModule = () => {
useCozyEvent('login', (data) => console.log('User:', data), { id: 'auth' });
return <div>Auth Module</div>;
};const NotificationModule = () => {
useCozyEvent('new-message', (msg) => console.log('Message:', msg), {
id: 'notifications',
});
return <div>Notifications</div>;
};Global Instance Fallback
If CozyEventProvider is missing, useCozyEvent falls back to the global instance.
useCozyEvent('global-event', (data) => console.log('Global event:', data));Best Practices
✅ Use meaningful event names to avoid conflicts.
✅ Leverage namespaces for better organization.
✅ Let useCozyEvent handle cleanup (no manual unsubscriptions).
✅ Use custom instances for modularity.
✅ Assign id to providers for debugging.
✅ Utilize the registry for easy instance management.
Benchmark Results
Emit:
The following are the benchmark results for 1,000,000 listeners (from fastest to slowest):
| Library | Operation | Rate (ops/sec) | Variability (%) | Runs Sampled | | --------------------------- | --------- | -------------- | --------------- | ------------ | | cozyEvent | emit | 4,095 | ±0.80% | 94 | | tseep | emit | 3,587 | ±1.85% | 91 | | braintree-event-emitter | emit | 3,431 | ±3.43% | 85 | | emitix | emit | 461 | ±2.41% | 84 | | eventemitter3 | emit | 180 | ±1.89% | 83 | | eventemitter2 | emit | 150 | ±2.45% | 76 | | node-event-emitter | emit | 120 | ±4.22% | 70 | | protobufjs-eventemitter | emit | 119 | ±0.70% | 77 | | event-emitter | emit | 91.98 | ±3.25% | 68 |
On:
| Library | ops/sec | Variability (%) | Runs Sampled | | --------------------------- | --------: | --------------: | -----------: | | cozyEvent | 7,048,823 | ±23.01% | 44 | | tseep | 6,699,486 | ±22.93% | 58 | | eventemitter2 | 4,759,473 | ±32.42% | 48 | | eventemitter3 | 2,760,536 | ±34.21% | 47 | | braintree-event-emitter | 2,493,323 | ±25.56% | 34 | | event-emitter | 1,578,055 | ±29.92% | 35 | | protobufjs-eventemitter | 1,533,468 | ±62.37% | 18 | | emitix | 886,668 | ±65.42% | 20 | | node-event-emitter | 116,289 | ±12.12% | 18 |
Once:
| Library | ops/sec | Variability (%) | Runs Sampled | | ---------------------- | --------: | --------------: | -----------: | | tseep | 7,025,903 | ±19.21% | 49 | | cozyEvent | 3,161,190 | ±36.82% | 35 | | eventemitter2 | 2,349,562 | ±28.37% | 42 | | eventemitter3 | 2,247,466 | ±32.67% | 42 | | event-emitter | 293,539 | ±115.29% | 17 | | node-event-emitter | 69,743 | ±77.57% | 18 | | emitix | 27,619 | ±50.74% | 6 |
Off:
| Library | ops/sec | Variability (%) | Runs Sampled | | --------------------------- | ----------: | --------------: | -----------: | | tseep | 241,358,834 | ±0.43% | 96 | | eventemitter3 | 237,546,830 | ±0.78% | 90 | | emitix | 86,382,491 | ±1.77% | 93 | | protobufjs-eventemitter | 84,816,381 | ±0.54% | 99 | | cozyEvent | 64,156,580 | ±1.30% | 89 | | node-event-emitter | 53,750,923 | ±2.40% | 91 | | eventemitter2 | 47,492,910 | ±1.99% | 86 | | braintree-event-emitter | 37,476,993 | ±0.49% | 96 | | event-emitter | 34,195,978 | ±0.99% | 96 |
RemoveAllListeners
| Library | ops/sec | Variability (%) | Runs Sampled | | ---------------------- | ----------: | --------------: | -----------: | | cozyEvent | 174,527,998 | ±0.86% | 89 | | eventemitter3 | 160,803,376 | ±2.56% | 91 | | eventemitter2 | 104,917,857 | ±2.26% | 94 | | node-event-emitter | 26,451,753 | ±3.37% | 90 | | tseep | 8,722,096 | ±2.12% | 93 |
License
Copyright (c) 2025 Mehmet Ergin Turk
Licensed under the MIT license. See the LICENSE file for details.
(Twitter/x: @papa_alpha_papa),
(Mastodon: @papa_alpha_papa)
(Bluesky: @erginturk.bsky.social)
