https://github.com/silent-watcher/resilia
A lightweight, decorator-based resilience stack for TypeScript: Circuit Breaker, Bulkhead, and Retry
https://github.com/silent-watcher/resilia
bulkhead circuit-breaker resilience retry-pattern stability
Last synced: about 1 month ago
JSON representation
A lightweight, decorator-based resilience stack for TypeScript: Circuit Breaker, Bulkhead, and Retry
- Host: GitHub
- URL: https://github.com/silent-watcher/resilia
- Owner: Silent-Watcher
- License: mit
- Created: 2025-12-25T18:13:50.000Z (6 months ago)
- Default Branch: master
- Last Pushed: 2026-01-01T02:57:15.000Z (6 months ago)
- Last Synced: 2026-03-29T01:56:46.935Z (3 months ago)
- Topics: bulkhead, circuit-breaker, resilience, retry-pattern, stability
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/resilia
- Size: 56.6 KB
- Stars: 8
- Watchers: 0
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Resilia
**The zero-dependency, decorator-based resilience stack for TypeScript.**
**Resilia** helps you build "unbreakable" Node.js applications by wrapping your critical methods in a professional-grade resilience stack. With a single `@Resilient` decorator, you gain a **Circuit Breaker**, **Bulkhead**, and **Exponential Retry** strategy—all pre-configured and fully observable.
---
## Features
* **Decorator-First DX:** Protect any class method with one line of code.
* **Circuit Breaker:** Prevent cascading failures with a sliding-window state machine (Closed, Open, Half-Open).
* **Bulkhead:** Limit concurrency and manage overflow queues to protect system resources.
* **Smart Retries:** Automatic retries with **Exponential Backoff** and **Jitter** to prevent "thundering herd" issues.
* **Full Observability:** Event-driven architecture with built-in counters and gauges for Prometheus/Grafana integration.
* **Zero Dependencies:** Extremely lightweight and fast.
---
## Installation
```bash
npm install resilia reflect-metadata
```
Make sure you have these flags enabled in your `tsconfig.json`:
```json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
```
---
## Quick Start
Simply tag your database calls or external API requests. Resilia handles the rest.
```typescript
import { Resilient } from 'resilia';
class PaymentService {
@Resilient({
concurrency: 5, // Max 5 simultaneous requests
queue: 10, // Max 10 waiting in line
maxRetries: 3, // Try 3 times before failing
errorThreshold: 0.5, // Trip circuit if >50% fail
sleepWindowMs: 30000 // Rest for 30s when tripped
})
async processTransaction(id: string) {
return await db.payments.create({ id });
}
}
```
---
## The Resilience Stack
Resilia executes your code through a three-layer "Matryoshka" security model:
### 1. The Circuit Breaker (Outer Layer)
Acts as a safety switch. If your service starts failing (e.g., the database is down), the circuit flips to **OPEN**.
* **Closed**: Everything is healthy.
* **Open**: Requests are "short-circuited" immediately to save resources.
* **Half-Open**: One "test" request is allowed through to check if the system recovered.
### 2. The Retry Strategy (Middle Layer)
Handles transient glitches. If a request fails, Resilia waits using **Exponential Backoff** (delaying longer each time) before trying again. It adds **Jitter** (randomness) to ensure multiple retrying services don't hit your server at the exact same millisecond.
### 3. The Bulkhead (Inner Layer)
Isolates resources. Even if one part of your app is slow, it won't crash the whole process. It limits how many copies of a specific function can run at once and provides a waiting room (queue) for the overflow.
---
## Observability & Events
Resilia is designed to be monitored. Every component is an `EventEmitter`, allowing you to hook into the system health in real-time.
```typescript
import { resilienceRegistry } from 'resilia';
resilienceRegistry.forEach(({ breaker, bulkhead }, key) => {
// Alert when a circuit trips
breaker.on('state:changed', (event) => {
console.error(`🚨 ALERT: ${key} changed from ${event.from} to ${event.to}`);
});
// Send metrics to your dashboard
bulkhead.on('request:rejected', () => {
metrics.increment(`bulkhead_overflow_${key}`);
});
});
```
### Metrics Snapshot
You can also grab a health snapshot at any time:
```typescript
const stats = bulkhead.getMetrics();
// { activeCount: 5, queueLength: 2, totalAccepted: 100, totalRejected: 1 }
```
---
## Configuration Reference
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `concurrency` | `number` | `10` | Max concurrent executions allowed for this method. |
| `queue` | `number` | `20` | Max requests that can wait if concurrency is full. |
| `maxRetries` | `number` | `3` | Number of retry attempts for transient errors. |
| `backoffMs` | `number` | `1000` | Initial delay for the exponential backoff. |
| `errorThreshold` | `number` | `0.5` | Percentage of failures (0.0 to 1.0) that trips the circuit. |
| `sleepWindowMs` | `number` | `30000` | How long the circuit stays OPEN before testing recovery. |
---
## Contributing
Contributions are welcome! If you have ideas for new resilience patterns (like Rate Limiting or Timeouts), feel free to open an issue or a PR.
---
## License
Distributed under the MIT License. See `LICENSE` for more information.
---
**Built with ❤️ for the Node.js community.** *Star this repo if it helped you sleep better at night!* ⭐