NATSrun is a lightweight TypeScript library that provides Express/Koa-like routing capabilities for NATS messages. It uses pattern matching to route messages to appropriate handlers based on NATS subjects, making it easy to build microservices with clean, maintainable code.
- Pattern-based message routing using NATS subject patterns
- Multiple handler support for the same subject
- Async/await support
- Configurable handler sorting strategies
- Zero dependencies (except TypeScript)
- TypeScript-first design with full type safety
npm install @gooseus/natsrunimport { NatsRun } from '@gooseus/natsrun';
// Create a new router
const router = new NatsRun();
// Add handlers for different subjects
router.add('user.created', async (msg, ctx, next) => {
console.log('New user created:', msg);
// Pass data to next handler
await next({ userId: msg.data.id });
});
router.add('user.*.updated', async (msg, ctx, next) => {
console.log(`User ${ctx.userId} updated:`, msg);
// Access data from previous handler
console.log('Previous handler data:', ctx);
});
// Handle incoming messages
await router.handle('user.created', { id: 1, name: 'John' });
await router.handle('user.123.updated', { name: 'John Doe' });NATSrun supports NATS-style subject pattern matching:
*matches a single token>matches one or more tokens- Exact matches take precedence over wildcards
Examples:
user.*matchesuser.created,user.updateduser.>matchesuser.created,user.123.updated,user.123.profile.updateduser.createdmatches exactlyuser.created
NATSrun supports three sorting strategies for handlers:
specificity(default): Handlers are sorted by pattern specificity (more specific first)insertion: Handlers are executed in the order they were addedcustom: Use your own sorting function
const router = new NatsRun({
sortStrategy: 'insertion' // or 'specificity' or 'custom'
});
// Custom sorting with metadata
router.add('user.updated', async (msg) => {
console.log('Handler 1:', msg);
}, { priority: 1 });
router.add('user.updated', async (msg) => {
console.log('Handler 2:', msg);
}, { priority: 2 });
// Custom sorting function
const router = new NatsRun({
sortStrategy: 'custom',
customSort: (a, b) => a.metadata.priority - b.metadata.priority
});The main router class that handles message routing.
constructor(opts?: {
sortStrategy?: 'specificity' | 'insertion' | 'custom';
customSort?: (a: NatsHandlersPayload, b: NatsHandlersPayload) => number;
})-
add(pattern: string, handle: Handler | Handler[], metadata?: Record<string, any>): void- Adds a handler for the given subject pattern
- Can accept a single handler or an array of handlers
- Optional metadata for custom sorting
-
match(subject: string): Handler[]- Returns all handlers that match the given subject
- Handlers are sorted according to the configured strategy
-
handle(subject: string, message: any, ctx?: Record<string, any>): Promise<Record<string, any>>- Executes all matching handlers for the given subject and message
- Returns the final context after all handlers have executed
type Handler = (msg: NatsMsg, ctx: Record<string, any>, next: (data?: any) => Promise<Record<string, any> | void>) => Promise<Record<string, any> | void>;
type NatsMsg = {
subject: string;
data: any;
};npm run buildThis project uses the built-in Node test runner with tsx for TypeScript support.
npm run testGenerate and view documentation:
npm run build:docs
http-server docsPlease read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
See CHANGELOG.md for a list of changes in each version.
MIT