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

immortal-js

v1.0.0

Published

Ultra-resilient Node.js runtime enhancement — Containment, Recovery, Isolation, Supervision, Observability

Readme

Immortal.js

Production-grade resilience framework for Node.js — five composable layers that make your services impossible to kill.

npm version TypeScript License: MIT Tests


What is Immortal.js?

Immortal.js is a monorepo of battle-tested resilience primitives for Node.js microservices. It implements a strict five-layer architecture:

┌──────────────────────────────────────────────────────┐
│  Layer 5 · Observability  (Metrics, Health, Logs)    │
├──────────────────────────────────────────────────────┤
│  Layer 4 · Supervision    (Cluster, Process restart) │
├──────────────────────────────────────────────────────┤
│  Layer 3 · Isolation      (Bulkhead, Worker threads) │
├──────────────────────────────────────────────────────┤
│  Layer 2 · Recovery       (Retry, Circuit Breaker)   │
├──────────────────────────────────────────────────────┤
│  Layer 1 · Containment    (Safe Zone, Error Trap)    │
└──────────────────────────────────────────────────────┘

Each layer is independently usable; together they provide defense-in-depth against every class of production failure.


Packages

| Package | Description | Version | |---------|-------------|---------| | @immortal/core | Core resilience primitives | 1.0.0 | | @immortal/fastify | Fastify integration plugin | 1.0.0 | | @immortal/nestjs | NestJS module + decorators | 1.0.0 | | @immortal/koa | Koa middleware | 1.0.0 | | @immortal/dashboard | Real-time health dashboard | 1.0.0 |


Quick Start

npm install @immortal/core
import { createImmortal, withRetry, CircuitBreaker } from '@immortal/core';

// 1. Initialize the runtime
const immortal = await createImmortal({
  logger: { level: 'info' },
  healthMonitor: { enabled: true },
  gracefulShutdown: { enabled: true, timeoutMs: 30_000 },
});

// 2. Add a circuit breaker around any I/O call
const breaker = new CircuitBreaker('payment-service', {
  threshold: 5,
  timeout: 60_000,
  halfOpenRequests: 2,
});

const result = await breaker.run(async () => {
  return await paymentApi.charge(amount);
});

// 3. Retry with exponential backoff
const data = await withRetry(
  () => fetch('https://api.example.com/data'),
  { maxAttempts: 3, baseDelayMs: 200, backoffFactor: 2 }
);

Installation

npm workspaces (monorepo)

git clone https://github.com/Brah-Timo/immortal-js.git
cd immortal-js
npm install
npm test

Single package

npm install @immortal/core

With framework adapter

# Fastify
npm install @immortal/core @immortal/fastify fastify

# NestJS
npm install @immortal/core @immortal/nestjs @nestjs/core @nestjs/common reflect-metadata

# Koa
npm install @immortal/core @immortal/koa koa

Core API

Layer 1 — Containment (Safe Zone)

Catches all unhandled errors at process and request boundaries.

import { AsyncBoundary, asyncBoundary, ErrorTrap, classifyError } from '@immortal/core';

// Classify errors for routing
const kind = classifyError(error);
// → 'operational' | 'programming' | 'transient' | 'external' | 'unknown'

// Wrap a handler with automatic boundary context
const safeFn = asyncBoundary(myHandler, { fallback: () => defaultResponse });

// Static boundary methods
AsyncBoundary.run(async () => {
  const ctx = AsyncBoundary.getContext();  // trace ID, request ID, etc.
});

// Global error trap (uncaught exceptions + unhandled rejections)
const trap = new ErrorTrap(bus);
trap.install();

Layer 2 — Recovery

Retry Engine with exponential backoff and jitter:

import { withRetry, withTimeout, calculateBackoff } from '@immortal/core';

const result = await withRetry(operation, {
  maxAttempts: 5,
  baseDelayMs: 100,
  backoffFactor: 2,
  jitter: true,
  retryOn: (err) => err.code === 'ECONNRESET',
});

const bounded = await withTimeout(operation, 5_000, 'payment-charge');

Circuit Breaker with half-open probing:

import { CircuitBreaker, CircuitBreakerRegistry } from '@immortal/core';

const cb = new CircuitBreaker('db', {
  threshold: 5,       // failures before opening
  timeout: 30_000,    // ms before trying half-open
  halfOpenRequests: 3,
});

// States: 'closed' | 'open' | 'half-open'
const state = cb.getCurrentState();

// Force state (testing)
cb.forceState('open');

// Registry for multi-service management
const registry = CircuitBreakerRegistry.getInstance();
registry.get('db').getCurrentState();

Fallback Cache — serve stale on failure:

import { RouteFallbackCache } from '@immortal/core';

const cache = new RouteFallbackCache({ maxEntries: 500, ttlMs: 60_000 });
cache.set('GET /products/42', productData, { ttlMs: 300_000 });

const stale = cache.get('GET /products/42');

Layer 3 — Isolation

Bulkhead Pool — limit concurrency per service:

import { BulkheadPool, BulkheadRegistry } from '@immortal/core';

const pool = new BulkheadPool('database', {
  maxConcurrent: 10,
  maxQueueSize: 50,
  defaultTimeoutMs: 5_000,
});

const result = await pool.run(async () => db.query(sql), 'high', 3_000);

const status = pool.getStatus();
// → { name, active, queued, maxConcurrent, maxQueueSize, rejected, totalExecuted }

Worker Sandbox — run untrusted code in a thread:

import { WorkerSandbox } from '@immortal/core';

const sandbox = new WorkerSandbox({ timeoutMs: 5_000, memoryLimitMb: 64 });
const result = await sandbox.execute(`return input * 2`, { input: 21 });
// → 42

Layer 4 — Supervision

Supervisor — manages named async processes with automatic restart:

import { Supervisor } from '@immortal/core';

const supervisor = new Supervisor({
  config: { maxRestartsInWindow: 5, windowMs: 60_000, baseRestartDelayMs: 1_000 },
  onEscalation: (id) => alertTeam(`Worker ${id} is broken!`),
});

supervisor.register('http-server', {
  spawnFn: () => startHttpServer(),
  terminate: (instance) => instance.close(),
});

// Get all worker states
const statuses = supervisor.getWorkerStatuses();
// → [{ id, state, restartCount, uptime, pid?, lastRestartTime? }]

await supervisor.stop('http-server');
await supervisor.stopAll();

Cluster Manager — multi-core process management:

import { ClusterManager } from '@immortal/core';

if (ClusterManager.isPrimary()) {
  const mgr = new ClusterManager({
    workerCount: 4,
    onEscalation: (id) => console.error(`Worker ${id} escalated`),
  });
  await mgr.start();
  // Zero-downtime rolling restart
  await mgr.rollingRestart();
} else {
  await startApp();
}

Layer 5 — Observability

Metrics Collector — system metrics snapshot:

import { MetricsCollector } from '@immortal/core';

const collector = new MetricsCollector();
const snapshot = collector.getSnapshot();
// → { timestamp, eventLoopLag, memory, cpu, handles, requests, circuits, bulkheads, workers }

Health Monitor — periodic health checks:

import { HealthMonitor } from '@immortal/core';

const monitor = new HealthMonitor(
  { checkIntervalMs: 30_000, eventLoopLagCriticalMs: 100 },
  bus,
  metricsCollector
);
monitor.start();

Memory Leak Guard — detect and react to memory growth:

import { MemoryLeakGuard } from '@immortal/core';

const guard = new MemoryLeakGuard({
  checkIntervalMs: 30_000,
  warningThresholdMb: 400,
  restartThresholdMb: 600,
  growthWindowCount: 5,
}, bus);

guard.start();

Diagnostics Channel — OpenTelemetry-compatible tracing:

import { DiagnosticsChannel } from '@immortal/core';

const dc = new DiagnosticsChannel({ otlpEndpoint: 'http://otel-collector:4318' });
dc.recordRequest({ route: '/api/users', method: 'GET', statusCode: 200, durationMs: 45 });

Plugins

Immortal.js has a first-class plugin system:

import {
  createImmortal,
  ConsoleLogPlugin,
  RequestTracingPlugin,
  createAnomalyDetectionPlugin,
  createSlackAlertPlugin,
} from '@immortal/core';

const immortal = await createImmortal({
  plugins: [
    ConsoleLogPlugin,
    RequestTracingPlugin,
    createAnomalyDetectionPlugin({ threshold: 0.1 }),
    createSlackAlertPlugin({ webhookUrl: process.env.SLACK_WEBHOOK! }),
  ],
});

Built-in plugins:

| Plugin | Description | |--------|-------------| | ConsoleLogPlugin | Structured JSON logging to stdout | | RequestTracingPlugin | Request ID propagation via AsyncLocalStorage | | createAnomalyDetectionPlugin | Statistical anomaly detection on metrics | | createSlackAlertPlugin | Slack webhook notifications for critical events |

Custom plugins:

import type { ImmortalPlugin } from '@immortal/core';

const myPlugin: ImmortalPlugin = {
  name: 'my-plugin',
  async onInit(ctx) {
    ctx.logger.info('Plugin initialized', { config: ctx.config });
  },
  async onShutdown(signal) {
    // cleanup
  },
};

Chaos Engineering

Test your resilience in staging:

import { ChaosEngine } from '@immortal/core';

const chaos = new ChaosEngine();

// Inject latency into specific routes
chaos.addFault({
  type: 'latency',
  probability: 0.1,         // 10% of requests
  minMs: 100,
  maxMs: 2000,
  targetRoutes: ['/api/orders'],
});

// Random errors
chaos.addFault({
  type: 'error',
  probability: 0.05,        // 5% error rate
  errorMessage: 'Chaos: simulated service failure',
});

// Wrap a handler
const chaosHandler = chaos.wrapHandler(originalHandler);

// Enable/disable at runtime
chaos.enable();
chaos.disable();

Framework Integrations

Fastify

import Fastify from 'fastify';
import immortalPlugin from '@immortal/fastify';

const app = Fastify();
await app.register(immortalPlugin, {
  circuitBreakers: true,
  bulkheads: true,
  metrics: true,
  gracefulShutdown: true,
});

See examples/fastify-microservice for a full example.

NestJS

import { Module } from '@nestjs/common';
import { ImmortalModule } from '@immortal/nestjs';

@Module({
  imports: [
    ImmortalModule.forRoot({
      logger: { level: 'info' },
      gracefulShutdown: { enabled: true },
    }),
  ],
})
export class AppModule {}

Decorators:

import { Bulkhead, Circuit, Retry } from '@immortal/nestjs';

@Injectable()
export class OrdersService {
  @Bulkhead({ pool: 'orders', maxConcurrent: 5 })
  @Circuit({ name: 'order-db', threshold: 3 })
  @Retry({ maxAttempts: 2 })
  async createOrder(dto: CreateOrderDto) {
    return this.db.orders.create(dto);
  }
}

See examples/nestjs-enterprise for a full example.

Koa

import Koa from 'koa';
import { immortalMiddleware } from '@immortal/koa';

const app = new Koa();
app.use(immortalMiddleware({ circuitBreakers: true, metrics: true }));

Configuration Reference

interface ImmortalConfig {
  logger?: {
    level?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
    transport?: 'console' | 'json' | 'pretty';
    prefix?: string;
  };
  healthMonitor?: {
    enabled?: boolean;
    checkIntervalMs?: number;
    eventLoopLagWarningMs?: number;
    eventLoopLagCriticalMs?: number;
    heapUsageWarningPercent?: number;
    heapUsageCriticalPercent?: number;
  };
  memoryGuard?: {
    enabled?: boolean;
    checkIntervalMs?: number;
    warningThresholdMb?: number;
    restartThresholdMb?: number;
    growthWindowCount?: number;
    adaptive?: boolean;
  };
  gracefulShutdown?: {
    enabled?: boolean;
    timeoutMs?: number;
    signals?: NodeJS.Signals[];
  };
  chaos?: {
    enabled?: boolean;
  };
  plugins?: ImmortalPlugin[];
}

Testing

# All tests
npm test --workspaces --if-present

# Core package only
cd packages/core && npm test

# Watch mode
cd packages/core && npm test -- --watch

# Coverage
cd packages/core && npm test -- --coverage

102 tests across 6 test suites — all passing.


Project Structure

immortal/
├── packages/
│   ├── core/                    # Main resilience library
│   │   ├── src/
│   │   │   ├── safe-zone/       # Layer 1: Containment
│   │   │   ├── recovery/        # Layer 2: Retry, CircuitBreaker, FallbackCache
│   │   │   ├── isolation/       # Layer 3: BulkheadPool, WorkerSandbox
│   │   │   ├── supervision/     # Layer 4: Supervisor, ClusterManager
│   │   │   ├── monitoring/      # Layer 5: Metrics, Health, MemoryGuard
│   │   │   ├── lifecycle/       # GracefulShutdown
│   │   │   ├── chaos/           # ChaosEngine
│   │   │   ├── plugins/         # Built-in plugins
│   │   │   ├── config/          # Defaults & validation
│   │   │   ├── event-bus.ts     # Typed internal event bus
│   │   │   ├── logger.ts        # Structured logger
│   │   │   ├── runtime.ts       # ImmortalRuntime orchestrator
│   │   │   ├── types.ts         # All TypeScript interfaces
│   │   │   └── index.ts         # Public API surface
│   │   └── test/                # Vitest test suites
│   ├── adapter-fastify/         # Fastify plugin
│   ├── adapter-nestjs/          # NestJS module
│   ├── adapter-koa/             # Koa middleware
│   └── dashboard/               # Real-time dashboard
├── examples/
│   ├── fastify-microservice/    # Complete Fastify example
│   └── nestjs-enterprise/       # Complete NestJS example
├── docs/
│   ├── api/                     # Per-module API docs
│   └── guides/                  # Integration guides
├── package.json                 # npm workspaces root
├── tsconfig.json                # TypeScript 5.4+ strict config
└── LICENSE                      # MIT

Contributing

See docs/CONTRIBUTING.md.


Changelog

See docs/CHANGELOG.md.


License

MIT © Immortal.js Contributors — see LICENSE.