Postboy Help

Postboy — a typed message bus for TypeScript

Postboy is a lightweight, framework-agnostic message bus for TypeScript applications. It replaces scattered service calls and deep component chains with a single typed bus: parts of your application exchange typed messages instead of calling each other, so the code stays decoupled and predictable as it grows.

The sole runtime dependency is RxJS (^7).

Component A → postboy.fire(new OrderPlacedEvent(id)) → bus → every subscriber of OrderPlacedEvent

What you get

Capability

How

Publish/subscribe

fire/sub/once over PostboyGenericMessage events

Async request/response

fireCallback over PostboyCallbackMessage<T> with typed results

Synchronous commands

exec over PostboyExecutor<T> — returns T directly

Cross-cutting concerns

staged middleware with cancellation

Lifecycle management

registrators and namespaces that tear down registrations in one call

Testability

the postboy-testing BDD toolkit

A companion package, @artstesh/postboy-testing, provides a recording mock and fluent assertions for testing postboy-based code.

A taste of Postboy

import { PostboyService, PostboyGenericMessage } from '@artstesh/postboy'; class OrderPlacedEvent extends PostboyGenericMessage { static readonly ID = 'shop.order.placed'; constructor(public readonly orderId: string) { super(); } } const postboy = new PostboyService(); // register before use (routing is keyed by the static ID) postboy.exec(new ConnectMessage(OrderPlacedEvent, new Subject<OrderPlacedEvent>())); postboy.sub(OrderPlacedEvent).subscribe((e) => console.log('order', e.orderId)); postboy.fire(new OrderPlacedEvent('ORD-42'));

Every message class declares its own unique static readonly ID — that string, not the class identity, is the routing key. It is the one rule that explains most of Postboy's behavior; see How it works.

Where to go next

07 September 2026