npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nl-framework/microservices

v0.3.5

Published

Microservices module for nl-framework with Dapr integration, NestJS-style message patterns, and pub/sub abstractions.

Readme

@nl-framework/microservices

Microservices module for nl-framework providing NestJS-style message patterns, event-driven architecture, and Dapr integration.

Features

  • Message Patterns: Decorate controller methods with @MessagePattern and @EventPattern to handle incoming messages
  • Client API: Publish events with emit() (fire-and-forget) or send requests with send() (request/response)
  • Dapr Integration: Built-in transport for Dapr sidecar with pub/sub support
  • Pluggable Transports: Abstract transport interface allows custom implementations
  • Logger Integration: Uses @nl-framework/logger for structured logging
  • Shared Decorators: Message handlers can reuse @UseGuards(), @UseInterceptors(), @UsePipes(), and @UseFilters() from @nl-framework/core, just like HTTP and GraphQL controllers

Installation

bun add @nl-framework/microservices

Quick Start

1. Configure Dapr Settings

Add to your config/default.yaml:

microservices:
  dapr:
    httpPort: 3500
    grpcPort: 50001
    componentsPath: ./dapr/components
  pubsub:
    name: redis-pubsub

2. Create a Message Handler Controller

import { Controller, Injectable } from '@nl-framework/core';
import { MessagePattern, EventPattern } from '@nl-framework/microservices';

@Controller()
@Injectable()
export class OrdersController {
  @MessagePattern('order.created')
  handleOrderCreated(context: MessageContext) {
    console.log('Order created:', context.data);
    return { status: 'processed' };
  }

  @EventPattern({ cmd: 'notify' })
  handleNotification(context: MessageContext) {
    console.log('Notification:', context.data);
  }
}

Decorator Tip: Import @UseGuards(), @UseInterceptors(), @UsePipes(), and @UseFilters() from @nl-framework/core to apply the same guard/interceptor/pipe/filter semantics to message handlers that you already use in HTTP or GraphQL controllers.

3. Register the Module

import { Module } from '@nl-framework/core';
import { createMicroservicesModule } from '@nl-framework/microservices';
import { OrdersController } from './orders.controller';

@Module({
  imports: [
    createMicroservicesModule({
      controllers: [OrdersController],
    }),
  ],
  controllers: [OrdersController],
})
export class AppModule {}

4. Publish Events

import { MicroserviceClient } from '@nl-framework/microservices';

@Injectable()
export class OrdersService {
  constructor(private readonly client: MicroserviceClient) {}

  async createOrder(data: unknown) {
    // Fire-and-forget event
    await this.client.emit('order.created', { orderId: 123, ...data });

    // Request/response (coming soon)
    // const result = await this.client.send('process.order', data);
  }
}

API Reference

Decorators

@MessagePatternDecorator(pattern)

Marks a method as a message handler for request/response patterns.

@MessagePatternDecorator('user.get')
async getUser(context: MessageContext) {
  return { id: 1, name: 'John' };
}

@EventPattern(pattern)

Marks a method as an event handler (fire-and-forget).

@EventPattern('user.created')
handleUserCreated(context: MessageContext) {
  console.log('New user:', context.data);
}

Client Methods

emit(pattern, data)

Publishes a fire-and-forget event.

await client.emit('order.created', { orderId: 123 });

send(pattern, data)

Sends a request and awaits a response (coming soon).

const result = await client.send('process.payment', { amount: 100 });

Exception Filters

Microservice handlers use the shared @UseFilters() decorator and the MicroserviceExceptionFilter interface to handle errors consistently with HTTP and GraphQL.

Scoped filters

import { Controller, Injectable, UseFilters } from '@nl-framework/core';
import {
  MessagePattern,
  MicroserviceExceptionFilter,
  MicroserviceExceptionContext,
} from '@nl-framework/microservices';

@Injectable()
class LoggingFilter implements MicroserviceExceptionFilter {
  catch(exception: Error, context: MicroserviceExceptionContext) {
    context.logger?.error({ pattern: context.pattern, exception });
    return { ok: false };
  }
}

@Controller()
@UseFilters(LoggingFilter)
export class OrdersConsumer {
  @MessagePattern('orders.create')
  async create(order: OrderDto) {
    throw new Error('Not implemented');
  }
}

Method-level filters run before class-level filters. Return a value from catch() to override the handler response; return undefined to continue to the next filter.

Global filters

import { registerMicroserviceExceptionFilter } from '@nl-framework/microservices';

registerMicroserviceExceptionFilter(new LoggingFilter());

Use registerMicroserviceExceptionFilter() or registerMicroserviceExceptionFilters() during bootstrap to apply filters to every handler. The dispatcher resolves tokens through dependency injection if available, then instantiates classes or uses provided instances.

Dapr Setup

1. Create Component Definition

Create dapr/components/redis-pubsub.yaml:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: redis-pubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
    - name: redisHost
      value: localhost:6379

2. Run with Dapr Sidecar

dapr run --app-id my-service --app-port 3000 --dapr-http-port 3500 -- bun run start

Transport Options

DaprTransport

import { DaprTransport } from '@nl-framework/microservices';

const transport = new DaprTransport({
  daprHost: 'localhost',
  daprHttpPort: 3500,
  pubsubName: 'redis-pubsub',
  logger: myLogger,
});

Custom Transport

Implement the Transport interface:

import type { Transport, MessagePattern } from '@nl-framework/microservices';

export class CustomTransport implements Transport {
  async connect(): Promise<void> {
    // Initialize connection
  }

  async close(): Promise<void> {
    // Cleanup
  }

  async emit(pattern: MessagePattern, data: unknown): Promise<void> {
    // Publish event
  }

  async send<TResult>(pattern: MessagePattern, data: unknown): Promise<TResult> {
    // Send request, await response
  }
}

Roadmap

  • [ ] Request/response pattern via Dapr service invocation
  • [ ] Subscription endpoint handlers for Dapr pub/sub
  • [ ] Message serialization/deserialization strategies
  • [ ] Retry policies and dead-letter queues
  • [ ] Integration with @nl-framework/http for hybrid services
  • [ ] Additional transport implementations (NATS, RabbitMQ, etc.)

License

MIT