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

@ferrow/health-check

v1.0.0

Published

Health check registry with timeout per check, critical flag, and express handler

Readme

health-check

CI

Health check registry with per-check timeout, critical vs. non-critical failures, and express-style handler. Runs checks concurrently, produces detailed report with latencies, and calculates overall status (healthy/degraded/unhealthy).

Installation

npm install health-check

Quick Start

import { HealthCheckRegistry } from 'health-check';

const health = new HealthCheckRegistry();

// Register checks
health.register('database', async () => {
  await db.query('SELECT 1');
}, { timeoutMs: 3000, critical: true });

health.register('cache', async () => {
  await redis.ping();
}, { timeoutMs: 2000, critical: false });

// Get status
const report = await health.status();
console.log(report.status); // 'healthy', 'degraded', or 'unhealthy'

// Express-style handler
const handler = await health.handler();
console.log(handler.statusCode); // 200 or 503

API

new HealthCheckRegistry(): HealthCheckRegistry

Create a health check registry.

register(name, checkFn, config?): void

Register a health check function.

health.register('mysql', checkFn, {
  timeoutMs: 5000,  // Default
  critical: false   // Default
});

Parameters:

  • name (string): Unique check identifier
  • checkFn (() => Promise): Async function that throws or completes normally
  • config (CheckConfig, optional):
    • timeoutMs (number, default: 5000): Max time before check times out
    • critical (boolean, default: false): If true, this failure triggers unhealthy status

status(): Promise<HealthReport>

Run all checks concurrently and return results.

interface HealthReport {
  status: 'healthy' | 'degraded' | 'unhealthy';
  timestamp: string; // ISO string
  checks: Record<string, {
    result: 'ok' | 'failed' | 'timed_out';
    latencyMs: number;
    error?: string;
  }>;
}

Status Logic:

  • healthy: All checks passed
  • degraded: One or more non-critical checks failed
  • unhealthy: Any critical check failed or timed out

handler(): Promise<{ statusCode: number; body: string }>

Express-style handler for GET /health. Returns JSON response.

const { statusCode, body } = await health.handler();
// statusCode: 200 if healthy, 503 if degraded or unhealthy
// body: JSON string of HealthReport

Check Results

Each check result can be:

  • 'ok': Check passed
  • 'failed': Check threw an error
  • 'timed_out': Check exceeded timeoutMs

Examples

Critical vs. Non-Critical

const health = new HealthCheckRegistry();

// Database failure → unhealthy
health.register('database', checkDB, { critical: true });

// Cache miss → degraded (not unhealthy)
health.register('cache', checkCache, { critical: false });

const report = await health.status();
// If DB fails: status = 'unhealthy'
// If cache fails (DB ok): status = 'degraded'
// If both fail: status = 'unhealthy'

Timeouts

health.register('slow_api', async () => {
  await fetch('https://slow-service.example.com/health');
}, { timeoutMs: 1000 }); // Times out after 1 second

const report = await health.status();
// If slow, result: 'timed_out', error: 'timeout after 1000ms'

Express Integration

import express from 'express';
import { HealthCheckRegistry } from 'health-check';

const app = express();
const health = new HealthCheckRegistry();

health.register('database', async () => {
  await db.query('SELECT 1');
}, { critical: true });

app.get('/health', async (req, res) => {
  const { statusCode, body } = await health.handler();
  res.status(statusCode).type('application/json').send(body);
});

app.listen(3000);

Concurrent Checks with Latency Tracking

const health = new HealthCheckRegistry();

health.register('api_1', async () => {
  await fetch('https://api-1.example.com/health');
});

health.register('api_2', async () => {
  await fetch('https://api-2.example.com/health');
});

const report = await health.status();
console.log(report.checks);
// {
//   api_1: { result: 'ok', latencyMs: 42 },
//   api_2: { result: 'failed', latencyMs: 105, error: 'HTTP 500' }
// }

Limits

  • Checks must throw to signal failure; returning normally means success.
  • No exponential backoff or retry per check; implement in the check function if needed.
  • Handler always returns 200 or 503; no support for 503 with retry-after.
  • No built-in metrics collection; latencies are reported but not aggregated.
  • Checks run concurrently with Promise.allSettled; they do not block each other.

License: MIT

Sponsored by Ferrow


Part of the ferrow-toolkit collection · Sponsored by Ferrow