A lightweight and flexible event bus for React, designed to simplify inter-component communication using event-driven architecture.
✅ Easy to integrate with any React project
✅ TypeScript support out of the box
✅ Supports both global and scoped events
✅ Handles dynamic event registration and cleanup
✅ Clean API for emitting and listening to events
✅ Fully compatible with React 19
Install the package using npm:
npm install react-ebusor with yarn:
yarn add react-ebusWrap your app with the EventProvider to initialize the event bus:
import React from "react";
import { EventProvider } from "react-ebus";
const App = () => {
return (
<EventProvider
registerEvents={{
userlogin: "user:login",
userlogout: "user:logout",
}}
allowAllEvents={false}
>
{/* If `allowAllEvents` is false, only registered events will be allowed */}
<YourComponent />
</EventProvider>
);
};
export default App;Use the useEventEmitter hook to emit events from any component.
import { useEventEmitter } from "react-ebus";
const YourComponent = () => {
const { emit, eventList } = useEventEmitter();
const handleLogin = () => {
emit("user:login", { id: 1, name: "John Doe" }); // Emit directly by event name
};
const handleLoginWithRegisteredEvent = () => {
emit(eventList.userlogin, { id: 1, name: "John Doe" }); // Emit using registered events to avoid typos
};
return (
<div>
<button onClick={handleLogin}>Login</button>
<button onClick={handleLoginWithRegisteredEvent}>
Login with Registered Event
</button>
</div>
);
};Use the useEventListener hook to listen for events.
import { useEventListener } from "react-ebus";
const YourComponent = () => {
const { unregister, unregisterAll } = useEventListener(
{
"user:login": (data) => {
console.log("User logged in:", data);
},
"user:logout": () => {
console.log("User logged out");
},
},
{ allowedAllEvents: false }
);
return (
<div>
<p>Listening for login and logout events...</p>
<button onClick={() => unregister("user:login")}>
Unregister Login Event
</button>
<button onClick={unregisterAll}>Unregister All Events</button>
</div>
);
};| Prop | Type | Required | Description |
|---|---|---|---|
registerEvents |
{[key:string]:string} |
❌ | List of allowed event names. |
allowAllEvents |
boolean |
❌ | If false, only registered events are allowed. |
| Prop | Type | Description |
|---|---|---|
emit |
(eventName: string, payload?: any) => void |
Function to emit an event with an optional payload. |
eventList |
{[key: string]: string} |
List of registered events. |
isEventAllowed |
(eventName: string) => boolean |
Function to check if an event is allowed. |
| Prop | Type | Required | Description |
|---|---|---|---|
eventListeners |
Record<string, EventHandler> |
✅ | Object mapping event names to handler functions. |
configuration |
Partial<UseEventListenerConfig> |
❌ | Configuration object for allowing unregistered events. |
| Prop | Type | Description |
|---|---|---|
allowedAllEvents |
boolean |
If true, allows emitting events even if unregistered. |
import React from "react";
import {
EventProvider,
useEventEmitter,
useEventListener,
} from "react-ebus";
const App = () => (
<EventProvider
registerEvents={{ customEvent: "custom:event" }}
allowAllEvents={false}
>
<ComponentA />
<ComponentB />
</EventProvider>
);
const ComponentA = () => {
const { emit } = useEventEmitter();
return (
<button onClick={() => emit("custom:event", { message: "Hello from A!" })}>
Emit Event
</button>
);
};
const ComponentB = () => {
useEventListener({
"custom:event": (data) => {
console.log("Event received:", data);
},
});
return <div>Listening for events...</div>;
};Types are included out of the box:
export type EventHandler = (...args: any[]) => void;
export interface UseEventListenerConfig {
allowedAllEvents?: boolean;
}npm run type-checknpm run buildnpm publish --access public✔️ Always define and register events in EventProvider.
✔️ Clean up event listeners to avoid memory leaks.
✔️ Use TypeScript to ensure type safety.
✔️ Handle unknown or unregistered events gracefully.
If you like this project, consider giving it a ⭐ on GitHub!
Created by Saurabh
This project is licensed under the MIT License.
✅ Updated with useEventEmitter and useEventListener changes.
✅ Improved formatting for better readability.
✅ Added demo link and GitHub star button.
✅ Fixed consistency across examples.