@philiprehberger/healthcheck
v0.2.1
Published
Production readiness health check builder with typed check results
Readme
@philiprehberger/healthcheck
Production readiness health check builder with typed check results
Installation
npm install @philiprehberger/healthcheckUsage
import { createHealthcheck, check } from '@philiprehberger/healthcheck';
const health = createHealthcheck([
check('database', async () => { await db.ping(); }),
check('redis', async () => { await redis.ping(); }),
check('api', async () => {
const res = await fetch('https://api.example.com/health');
if (!res.ok) throw new Error(`Status ${res.status}`);
}),
]);
// Express/Fastify handler
app.get('/health', async (req, res) => {
const result = await health();
res.status(result.status === 'healthy' ? 200 : 503).json(result);
});Check Dependencies
Use dependsOn to ensure a check only runs after its dependencies pass. If a dependency fails, the dependent check is automatically marked unhealthy.
import { createHealthcheck, check } from '@philiprehberger/healthcheck';
const health = createHealthcheck([
check('database', async () => { await db.ping(); }),
check('migrations', async () => { await db.checkMigrations(); }, {
dependsOn: ['database'],
}),
check('seed-data', async () => { await db.checkSeeds(); }, {
dependsOn: ['database', 'migrations'],
}),
]);Degraded Status
Configure a threshold to distinguish between "degraded" and "unhealthy". When the percentage of passing checks is at or above the threshold, the overall status is "degraded" instead of "unhealthy".
import { createHealthcheck, check } from '@philiprehberger/healthcheck';
const health = createHealthcheck(
[
check('database', async () => { await db.ping(); }),
check('redis', async () => { await redis.ping(); }),
check('cdn', async () => { await cdn.ping(); }),
check('search', async () => { await search.ping(); }),
],
{ degradedThreshold: 50 },
);
// If 3 of 4 pass (75%) -> "degraded" (above 50% threshold)
// If 1 of 4 pass (25%) -> "unhealthy" (below 50% threshold)
// If 4 of 4 pass (100%) -> "healthy"Check Grouping
Organize checks into named groups for structured health reports. Each group gets its own aggregated status.
import { createHealthcheck, check, group } from '@philiprehberger/healthcheck';
const health = createHealthcheck([
...group('database', [
check('postgres', async () => { await pg.ping(); }),
check('migrations', async () => { await pg.checkMigrations(); }),
]),
...group('cache', [
check('redis', async () => { await redis.ping(); }),
check('memcached', async () => { await memcached.ping(); }),
]),
...group('external', [
check('stripe', async () => { await stripe.ping(); }),
check('sendgrid', async () => { await sendgrid.ping(); }),
]),
]);
const result = await health();
// result.groups['database'].status => 'healthy'
// result.groups['cache'].checks['redis'].status => 'healthy'Per-Check Timeout
Set a timeout per check in milliseconds. If the check does not complete within the timeout, it is marked unhealthy with a timeout error.
import { createHealthcheck, check } from '@philiprehberger/healthcheck';
const health = createHealthcheck([
check('database', async () => { await db.ping(); }, { timeout: 3000 }),
check('external-api', async () => {
const res = await fetch('https://slow-api.example.com/health');
if (!res.ok) throw new Error(`Status ${res.status}`);
}, { timeout: 5000 }),
]);Response
{
"status": "healthy",
"checks": {
"database": { "status": "healthy", "duration": 12 },
"redis": { "status": "healthy", "duration": 3 },
"api": { "status": "healthy", "duration": 45 }
},
"timestamp": "2026-03-13T10:00:00.000Z"
}API
| Export | Description |
|--------|-------------|
| createHealthcheck(checks, config?) | Returns async function that runs all checks, respecting dependencies |
| check(name, fn, options?) | Define a named health check with optional configuration |
| group(name, checks) | Assign a group name to an array of checks |
CheckOptions
| Property | Type | Description |
|----------|------|-------------|
| dependsOn | string[] | Names of checks that must pass before this check runs |
| timeout | number | Timeout in milliseconds; check fails if exceeded |
| group | string | Group name for categorizing this check |
HealthcheckConfig
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| degradedThreshold | number | 50 | Percentage (0-100) of checks that must pass for "degraded" instead of "unhealthy" |
HealthResult
| Property | Type | Description |
|----------|------|-------------|
| status | 'healthy' \| 'degraded' \| 'unhealthy' | Overall status |
| checks | Record<string, CheckResult> | Per-check results |
| groups | Record<string, GroupResult> | Per-group aggregated results (present when groups are used) |
| timestamp | string | ISO timestamp |
CheckResult
| Property | Type | Description |
|----------|------|-------------|
| status | 'healthy' \| 'degraded' \| 'unhealthy' | Check status |
| duration | number | Execution time in milliseconds |
| error | string | Error message (when unhealthy) |
| group | string | Group name (when assigned) |
GroupResult
| Property | Type | Description |
|----------|------|-------------|
| status | 'healthy' \| 'degraded' \| 'unhealthy' | Aggregated group status |
| checks | Record<string, CheckResult> | Checks belonging to this group |
Development
npm install
npm run build
npm testSupport
If you find this project useful:
