
Type-safe message bus in TypeScript
Building decoupled applications often requires a reliable way to handle messages between components. I have implemented a minimal, type-safe message bus that leverages TypeScript's type system: https://github.com/hvalls/typed-bus.
Usage
// 1. Define your message interfaces
interface AppMessages extends MessageRegistry {
'user.create': {
in: { name: string; email: string };
out: { id: string; name: string; email: string };
};
'email.send': {
in: { message: string; to: string; };
out: { sent: boolean };
};
}
// 2. Define your message handlers
const bus = createBus<AppMessages>()
.handle('user.create', async ({ name, email }) => {
const id = createUser(name, email):
return { id, name, email };
})
.handle('email.send', async ({ message, to }) => {
const sent = sendEmail(message, to);
return { sent: true };
});
// 3. Type-safe execution
const user = await bus.execute('user.create', {
name: 'John',
email: 'john@example.com'
});
Benefits
- Type safety: Full compile-time checking for message names and payloads
- Decoupling: Components communicate through contracts, not direct dependencies
- Simplicity: Minimal API with fluent registration
This pattern is particularly useful for implementing CQRS, event-driven architectures, or any scenario where you need type-safe message passing between application layers.