Frontend applications are becoming increasingly complex, with components and modules needing to communicate across the application without creating tight coupling. While solutions like Redux or global state management tools work well for application state, they can be overkill for simple event-based communication or introduce unnecessary complexity.
Today, I'm excited to introduce EventFlow, a lightweight, type-safe event broker designed specifically for frontend applications.
What is EventFlow?
EventFlow is a TypeScript-first event broker that provides a simple yet powerful way to handle events in your frontend applications. It combines the simplicity of event emitters with the safety of TypeScript, making it an ideal choice for modern web applications.
Key Features
- 🎯 Type Safety: Full TypeScript support with type inference for events and their payloads
- ⚡ Lightweight: Zero dependencies for core functionality
- 🔌 Middleware System: Extensible through a powerful middleware system
- 🛡️ Error Handling: Configurable error policies for robust applications
- ⚛️ React Integration: First-class React support with hooks and context
- 📦 Tree-shakeable: Only bundle what you use
Why Another Event Library?
While there are many event libraries available, EventFlow addresses several common challenges in frontend development:
- Type Safety: Unlike traditional event emitters, EventFlow ensures your events and their payloads are fully typed.
- Decoupled Communication: Enable components to communicate without direct dependencies.
- Cross-Cutting Concerns: Handle application-wide concerns through the middleware system.
- Framework Independence: Works with any JavaScript environment while providing first-class React support.
- Predictable Error Handling: Configure how your application behaves when events fail.
Getting Started
Installation is straightforward:
# Using npm
npm install @thesmilingsloth/eventflow-core
npm install @thesmilingsloth/eventflow-react # Optional React integration
# Using pnpm
pnpm add @thesmilingsloth/eventflow-core
pnpm add @thesmilingsloth/eventflow-react # Optional React integration
Basic Usage
import { createEventBroker } from "@thesmilingsloth/eventflow-core";
// Define your events
interface MyEvents {
"user:login": {
userId: string;
timestamp: number;
};
"app:notification": {
message: string;
type: "success" | "error";
};
}
// Create broker
const broker = createEventBroker<MyEvents>({
// Enable console logging middleware
logger: true,
// Configure max listeners per event
maxListeners: 10,
// Add custom middlewares
middlewares: [
// Example: Analytics middleware
(next) => (event) => {
console.log(`[Analytics] Event ${event.name} triggered`);
next(event);
},
// Example: Error tracking middleware
(next) => (event) => {
try {
next(event);
} catch (error) {
console.error(`[Error] in event ${event.name}:`, error);
throw error;
}
},
],
});
// Subscribe to events
const unsubscribe = broker.on("user:login", (data) => {
console.log(`User ${data.userId} logged in`);
});
// Emit events
broker.emit("user:login", {
userId: "123",
timestamp: Date.now(),
});
React Integration
The React integration package provides hooks for seamless integration with React components:
import {
EventBrokerProvider,
useEventListener,
useEventEmitter,
} from "@thesmilingsloth/eventflow-react";
function App() {
return (
<EventBrokerProvider broker={broker}>
<LoginButton />
<NotificationListener />
</EventBrokerProvider>
);
}
function LoginButton() {
const emitLogin = useEventEmitter("user:login");
return (
<button
onClick={() =>
emitLogin({
userId: "123",
timestamp: Date.now(),
})
}
>
Login
</button>
);
}
function NotificationListener() {
useEventListener("app:notification", (data) => {
alert(`${data.type}: ${data.message}`);
});
return null;
}
Advanced Features
Middleware System
EventFlow's middleware system allows you to intercept and transform events:
const analyticsMiddleware: Middleware<MyEvents> = (next) => (event) => {
// Before event
trackEvent(event.name, event.data);
// Process event
next(event);
// After event
console.log("Event processed:", event.name);
};
broker.use(analyticsMiddleware);
Error Handling
Configure how your application handles errors:
const broker = createEventBroker<MyEvents>({
errorPolicy: {
onListenerError: "continue",
onEmitError: "stop",
onMiddlewareError: (error, event) => {
reportError(error);
},
},
});
Use Cases
EventFlow is particularly useful for:
- Cross-Component Communication: When components need to communicate without direct coupling
- Application-Wide Events: For handling global notifications, theme changes, or user actions
- Analytics and Logging: Using middleware to track events across your application
- State Synchronization: When multiple components need to react to the same state changes
- Error Handling: Centralizing error handling and reporting
Conclusion
EventFlow brings type-safe event handling to frontend applications with a focus on developer experience and flexibility. Whether you're building a small React application or a large-scale frontend system, EventFlow provides the tools you need for robust event-based communication.
Try it out today and let me know what you think! The project is open source and contributions are welcome.
Top comments (0)