Skip to content

binarygeotech/elysia-microservice

Elysia Microservice Framework

A modular, transport-agnostic microservices framework for Elysia

npm version License GitHub stars Contributor Covenant

Build production-ready microservices with Elysia's speed and simplicity


✨ Features

  • πŸ”Œ Plugin Mode - Seamless integration with Elysia (HTTP + Microservice)
  • ⚑ Standalone Mode - Pure microservice applications without HTTP
  • 🎯 Advanced Pattern Matching - Wildcards (user.*), regex, and catchall handlers
  • πŸ›‘οΈ Guards & Middleware - Hierarchical DI system with global, group, and handler scopes
  • 🎭 Middleware & Guards - Authorization guards, request enrichment middleware, cross-cutting concerns
  • πŸ”€ Transport Agnostic - Support for TCP, TLS, NATS, Redis, and Kafka
  • πŸ“¦ Modular - Install only what you need, tree-shakable bundles
  • πŸ”„ Service Discovery - Static and DNS-based service discovery
  • βš–οΈ Load Balancing - Round-robin with failure tracking
  • πŸ›‘οΈ Resilience - Circuit breaker, retries, and timeouts
  • 🎭 Chaos Engineering - Inject failures and latency for testing
  • πŸ”— NestJS Compatible - Use NestJS decorators with Elysia
  • 🧩 Parameter Decorators - @Payload(), @Ctx(), and @App() for handler injection
  • πŸ“Š Connection Pooling - Automatic client pooling with failover
  • πŸͺ Lifecycle Hooks - onBefore/onAfter hooks for cross-cutting concerns
  • πŸ₯ Health Checks - Built-in health and readiness endpoints (hybrid mode)
  • πŸ“ TypeScript First - Full type safety with excellent IntelliSense

πŸ“š Documentation


πŸ“¦ Packages

This monorepo contains the following packages:

Core

Utilities

Transport Servers

Clients

Adapters


πŸš€ Quick Start

Installation

# Core + TCP transport (simplest setup)
bun add @elysia-microservice/core @elysia-microservice/transport-tcp @elysia-microservice/client-tcp elysia

Your First Microservice

server.ts

import { Elysia } from 'elysia';
import { Microservice } from '@elysia-microservice/core';

const app = new Elysia()
  .use(Microservice({ 
    server: { transport: 'tcp', options: { port: 4000 } },
    hybrid: true
  }))
  .onMsMessage('user.get', async (ctx) => {
    return { id: ctx.data.id, name: 'John Doe' };
  })
  .onMsEvent('user.created', (ctx) => {
    console.log('User created:', ctx.data);
  })
  .get('/', () => 'Hello HTTP!')
  .listen(3000);

console.log('πŸš€ HTTP: http://localhost:3000');
console.log('πŸ”Œ Microservice: tcp://localhost:4000');

client.ts

import { createTcpClient } from '@elysia-microservice/client-tcp';

const client = createTcpClient({ host: '127.0.0.1', port: 4000 });

// Request/response
const user = await client.send('user.get', { id: 1 });
console.log(user); // { id: 1, name: 'John Doe' }

// Fire-and-forget event
await client.emit('user.created', { id: 2, name: 'Jane' });

await client.close();

πŸ‘‰ Read the full Getting Started Guide


🎯 Key Concepts

Messages vs Events

Messages (Request/Response):

  • Client waits for response
  • Use .onMsMessage() on server, .send() on client
  • For queries and commands needing confirmation

Events (Fire-and-Forget):

  • Client doesn't wait for response
  • Use .onMsEvent() on server, .emit() on client
  • For notifications and side effects

Pattern Matching

// Exact match
.onMsMessage('user.get', handler)

// Wildcard - matches user.create, user.update, etc.
.onMsMessage('user.*', handler)

// Regex - matches user.create or user.update only
.onMsMessage(/^user\.(create|update)$/, handler)

// Catchall - handles unmatched patterns
.onMsCatchallMessage((pattern, data) => {
  return { error: 'Pattern not found' };
})

Learn more about Pattern Matching β†’

MessageContext

All handlers receive a structured context:

.onMsMessage('user.*', (ctx) => {
  console.log(ctx.pattern);  // Matched pattern: "user.create"
  console.log(ctx.data);     // Payload: { name: "John" }
  console.log(ctx.meta);     // Transport metadata
  return { success: true };
})

🧭 NestJS-Style Decorators (Adapters)

Microservice options (including adapters)

const app = new Elysia()
  .use(Microservice({
    hybrid: true,
    server: { transport: 'tcp', options: { port: 4000 } },
    clients: {},
    adapters: [
      {
        class: NestAdapter,
        initializer: (adapter, registry) => {
          adapter.init(registry, new UserController());
        },
      },
    ],
  }));

Adapters let you register controller classes once, each adapter can optionally receive an initializer to wire controllers.

Use the Nest adapter with familiar method decorators and parameter injections:

  • Method decorators: @MessagePattern() (request/response), @EventPattern() (fire-and-forget)
  • Parameter decorators: @Payload(), @Ctx(), @App()

To use decorators, update the following in your tsconfig.json file:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true   // optional, but common with Nest-style decorators
  }
}
import { MessagePattern, EventPattern, Payload, Ctx, App } from '@elysia-microservice/core';
import type { MicroserviceContext } from '@elysia-microservice/core';
import type { ElysiaInstance } from 'elysia';
import { from, Observable } from 'rxjs';

class UserController {
  @MessagePattern('user.get')
  getUser(
    @Payload('id') id: number,
    @Ctx() ctx: MicroserviceContext,
    @App() app: ElysiaInstance
  ) {
    app.log?.info?.(`Request trace: ${ctx.traceId}`);
    return { id, name: 'John Doe' };
  }

  // Event handler can also return an Observable stream
  @EventPattern('user.activity')
  activityStream(): Observable<number> {
    return from([1, 2, 3]);
  }
}

πŸ”Œ Supported Transports

TCP (Simple & Fast)

bun add @elysia-microservice/transport-tcp @elysia-microservice/client-tcp

TLS (Secure TCP)

bun add @elysia-microservice/transport-tls @elysia-microservice/client-tls

NATS (Message Broker)

bun add @elysia-microservice/transport-nats @elysia-microservice/client-nats nats

Redis (Pub/Sub)

bun add @elysia-microservice/transport-redis @elysia-microservice/client-redis redis

Kafka (Event Streaming)

bun add @elysia-microservice/transport-kafka @elysia-microservice/client-kafka kafkajs

πŸ› οΈ Development

Build All Packages

cd base
bun install
make build

Using Makefile

# Show all available commands
make help

# Build packages
make build              # Build all packages
make rebuild            # Clean and rebuild

# Run tests
make test              # All tests
make test-unit         # Unit tests only
make quick-test        # Fast unit tests (no build)

# Development
make dev               # Watch mode
make check             # Quick validation (build + test + lint)
make validate          # Full validation (clean + install + build + test)

# Publishing (maintainers only)
make version VERSION=0.2.0  # Update version
make publish-dry            # Test publish
make publish                # Publish to npm

Run Tests

make test              # All tests
make test-unit         # Unit tests only
make test-integration  # Integration tests

Clean Build Artifacts

make clean

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Quick Contribution Steps

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Commit your changes (git commit -m 'feat(core): add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Please read our Code of Conduct before contributing.


πŸ“„ License

MIT License - see LICENSE file for details.


πŸ”— Links


Built with ❀️ using Elysia and Bun

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors