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

health-chk

v2.0.0

Published

A lightweight, dependency-free health check, readiness, and liveness library for Node.js applications — with Express, Fastify, and plain HTTP adapters, dependency monitoring, timeouts/retries, and full TypeScript support.

Readme

health-chk

A lightweight, zero runtime dependency health check, readiness, and liveness library for Node.js applications — with first-class Express, Fastify, and plain http support, dependency monitoring, timeouts/retries, and full TypeScript types.

npm license

v2.0 is a breaking rewrite. See CHANGELOG.md for migration notes from v1.


Features

  • /health, /ready, and /live endpoints with standard, predictable payloads
  • Register dependency checks (database, cache, external APIs, anything async)
  • Per-check timeout and retry support so one hung dependency can't hang your probes
  • Three status levels — healthy / warning / unhealthy — with critical vs. non-critical checks
  • Adapters for Express, Fastify, and plain Node http — zero required peer dependencies
  • Production-safe error handling (raw error details hidden outside development by default)
  • Pluggable logging (console, custom, or disabled)
  • Full TypeScript types, dual CommonJS + ESM build

Installation

npm install health-chk

Basic Usage

const HealthCheck = require("health-chk").default; // or: const { HealthCheck } = require("health-chk");

const health = new HealthCheck({
  service: "orders-api",
  version: "1.4.0",
});

health.addCheck("mongodb", async () => {
  await mongoose.connection.db.stats();
  return true;
});

const result = await health.getHealth();
console.log(result);
// {
//   status: "healthy",
//   timestamp: "2026-07-28T12:00:00.000Z",
//   uptime: 5123.4,
//   service: "orders-api",
//   version: "1.4.0",
//   environment: "production",
//   checks: { mongodb: { status: "up", responseTime: 12 } }
// }

ESM / TypeScript

import HealthCheck from "health-chk";

const health = new HealthCheck({ service: "orders-api", version: "1.4.0" });

Express Integration

const express = require("express");
const HealthCheck = require("health-chk").default;
const { expressHealthCheck } = require("health-chk");

const app = express();
const health = new HealthCheck({ service: "orders-api", version: "1.4.0" });

health.addCheck("mongodb", async () => {
  await mongoose.connection.db.stats();
  return true;
});

health.addCheck(
  "payment-service",
  async () => checkPaymentAPI(),
  { timeout: 3000, retries: 2, critical: true }
);

// Mounts GET /health, GET /ready, GET /live
app.use(expressHealthCheck(health));

app.listen(3000);

Prefer to mount routes individually? Use expressHandlers:

const { expressHandlers } = require("health-chk");
const { health: healthHandler, ready, live } = expressHandlers(health);

app.get("/health", healthHandler);
app.get("/ready", ready);
app.get("/live", live);

Custom paths:

app.use(expressHealthCheck(health, {
  healthPath: "/healthz",
  readyPath: "/readyz",
  livePath: "/livez",
}));

Fastify Integration

const Fastify = require("fastify");
const HealthCheck = require("health-chk").default;
const { fastifyHealthCheck } = require("health-chk");

const app = Fastify();
const health = new HealthCheck({ service: "orders-api" });
health.addCheck("redis", async () => redisClient.ping() === "PONG");

app.register(fastifyHealthCheck(health));
app.listen({ port: 3000 });

Plain Node http Integration

const http = require("http");
const HealthCheck = require("health-chk").default;
const { httpHealthCheck } = require("health-chk");

const health = new HealthCheck({ service: "orders-api" });
const handleHealth = httpHealthCheck(health);

http.createServer((req, res) => {
  if (handleHealth(req, res)) return;
  // ...your app's routing
}).listen(3000);

Kubernetes Usage

/health gives a full diagnostic snapshot; /ready and /live are the two probes Kubernetes actually needs — kept intentionally cheap and separate so a slow dependency check never takes your pod out of rotation via the liveness probe.

livenessProbe:
  httpGet:
    path: /live
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3
  • Liveness (/live) always returns { "status": "alive" } with a 200 — it never touches dependency checks, so a flaky database won't cause Kubernetes to kill and restart a perfectly healthy process.
  • Readiness (/ready) runs all registered checks and returns 503 when any critical check is down, so the pod is pulled from the load balancer until it recovers.

Custom Checks

health.addCheck(
  "payment-service",
  async () => {
    const ok = await checkPaymentAPI();
    return ok; // boolean
  },
  { timeout: 3000, retries: 2, critical: true }
);

// Or register with more detail via .register()
health.register({
  name: "redis",
  critical: false, // failure only produces a "warning", never "unhealthy"
  check: async () => {
    const pong = await redisClient.ping();
    return { status: pong === "PONG" ? "up" : "down", message: `ping: ${pong}` };
  },
});

A check function may:

  • return/resolve true → status: "up"
  • return/resolve false → status: "down"
  • return/resolve undefined (or throw nothing) → status: "up"
  • return/resolve { status: "up" | "down" | "warning", message?, error? } for full control
  • throw / reject → treated as status: "down" (error message sanitized outside development)

Timeouts & Retries

const health = new HealthCheck({
  timeout: 3000, // default for all checks (ms)
  retries: 1,    // default retry count for all checks
  retryDelay: 100,
});

// Per-check overrides:
health.addCheck("slow-report-service", checkFn, { timeout: 8000, retries: 3, retryDelay: 250 });

A check that exceeds its timeout, or throws on every attempt (including retries), is marked "down" — it never hangs the endpoint.

Status Levels

| Status | Meaning | | ----------- | ---------------------------------------------------------------- | | healthy | All critical checks are up. | | warning | A non-critical check is down/warning, but nothing critical failed. | | unhealthy | At least one critical check is down. |


API Reference

new HealthCheck(options?)

| Option | Type | Default | Description | | -------------- | ------------------------ | ---------------------------------------- | --------------------------------------------- | | service | string | "application" | Reported service name | | version | string | npm_package_version env var or "0.0.0" | Reported app version | | environment | string | NODE_ENV or "development" | Reported environment | | timeout | number | 3000 | Default per-check timeout (ms) | | retries | number | 0 | Default per-check retry count | | retryDelay | number | 100 | Delay between retries (ms) | | exposeErrors | boolean | true outside production | Whether raw error messages are included | | logger | boolean \| Logger | false | true for console logging, or a custom logger | | envKeys | string[] | [] | Allowlisted env vars to include in /health |

Methods

  • health.register(definition) — register a check via { name, check, critical?, timeout?, retries?, retryDelay? }
  • health.addCheck(name, checkFn, options?) — shorthand for register
  • health.removeCheck(name) — unregister a check
  • health.listChecks() — list registered check names
  • health.configure(options) — merge new options after construction
  • health.getHealth() — returns the /health payload (Promise<HealthResponse>)
  • health.getReadiness() — returns the /ready payload (Promise<ReadinessResponse>)
  • health.getLiveness() — returns the /live payload (LivenessResponse, synchronous)

Adapters

  • expressHealthCheck(health, options?) — combined Express middleware for all three routes
  • expressHandlers(health) — { health, ready, live } individual Express handlers
  • fastifyHealthCheck(health, options?) — Fastify plugin
  • httpHealthCheck(health, options?) — plain http/https request handler, returns true if it handled the request

All adapters accept { healthPath, readyPath, livePath } to override the default /health, /ready, /live routes.


TypeScript Usage

import HealthCheck, {
  createHealthCheck,
  expressHealthCheck,
  type HealthCheckDefinition,
  type HealthResponse,
  type CheckResult,
} from "health-chk";

const health: HealthCheck = createHealthCheck({ service: "orders-api" });

const dbCheck: HealthCheckDefinition = {
  name: "postgres",
  critical: true,
  check: async (): Promise<boolean> => {
    await pool.query("SELECT 1");
    return true;
  },
};
health.register(dbCheck);

const result: HealthResponse = await health.getHealth();
const dbResult: CheckResult | undefined = result.checks?.postgres;

Security Notes

  • Raw error messages/stacks from failing checks are hidden by default in production (NODE_ENV=production) — only a generic "Health check failed" message is returned unless exposeErrors: true is set explicitly.
  • Environment variables are never included in responses unless you explicitly allowlist keys via envKeys.
  • register()/addCheck() validate that name and check are present, failing fast with a clear error at registration time rather than at request time.

Testing

npm test              # run the Jest suite
npm run test:coverage # run with coverage
npm run typecheck     # tsc --noEmit
npm run build         # produce dist/ (CJS + ESM + .d.ts)

License

MIT © 2025 Gulam Ashraf. See LICENSE.