
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
vitals-node
Advanced tools
Multi-framework health monitoring & system metrics for NestJS, Express, and Bun
Multi-framework health monitoring and system metrics for Node.js applications. Supports NestJS, Express, and Bun with zero-config setup.
npm install vitals-node
# or
yarn add vitals-node
# or
pnpm add vitals-node
# or
bun add vitals-node
import express from 'express';
import { expressPulse } from 'vitals-node/express';
const app = express();
app.use('/health', expressPulse({
dashboard: true,
alerts: {
line: { token: process.env.LINE_NOTIFY_TOKEN }
}
}));
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('Dashboard: http://localhost:3000/health/dashboard');
});
import { Module } from '@nestjs/common';
import { NestPulseModule } from 'vitals-node';
@Module({
imports: [
NestPulseModule.forRoot({
path: '/health',
dashboard: true,
alerts: {
line: { token: process.env.LINE_NOTIFY_TOKEN }
}
})
]
})
export class AppModule {}
import { bunPulse } from 'vitals-node/bun';
const pulse = bunPulse({ dashboard: true });
Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname.startsWith('/health')) {
return pulse.handler(req);
}
return new Response('OK');
}
});
| Endpoint | Description |
|---|---|
GET /health | Basic health status (JSON) |
GET /health/detailed | Full metrics with health checks |
GET /health/dashboard | Real-time HTML dashboard |
GET /health/metrics | Prometheus format metrics |
GET /health/history | Metrics history |
GET /health/alerts | Alert history |
POST /health/test-alerts | Test notification channels |
interface VitalsConfig {
// Base path for health endpoints (default: '/health')
path?: string;
// Enable dashboard UI (default: true)
dashboard?: boolean;
// Metrics collection interval in ms (default: 5000)
collectInterval?: number;
// Timezone for display (default: 'Asia/Bangkok')
timezone?: string;
// Enable Prometheus export (default: true)
prometheus?: boolean;
// Alert configuration
alerts?: {
// Alert thresholds
thresholds?: {
cpu?: number; // Default: 80%
memory?: number; // Default: 90%
disk?: number; // Default: 85%
responseTime?: number; // Default: 3000ms
};
// Cooldown between alerts (default: 5 minutes)
cooldown?: number;
// LINE Notify
line?: {
token: string;
enabled?: boolean;
};
// Email (SMTP)
email?: {
host: string;
port: number;
secure?: boolean;
user: string;
password: string;
from: string;
to: string[];
enabled?: boolean;
};
// Telegram
telegram?: {
botToken: string;
chatId: string;
enabled?: boolean;
};
};
// Custom health checks
healthChecks?: HealthCheckDefinition[];
}
The metrics response includes:
{
cpu: {
usage: 45.5, // Current CPU usage %
cores: 8, // Number of CPU cores
model: "Intel...", // CPU model name
speed: 3.2 // CPU speed in GHz
},
memory: {
total: 16384, // Total memory in MB
used: 8192, // Used memory in MB
free: 8192, // Free memory in MB
percentage: 50 // Usage percentage
},
disk: {
total: 512000, // Total disk in MB
used: 256000, // Used disk in MB
free: 256000, // Free disk in MB
percentage: 50 // Usage percentage
},
process: {
uptime: 86400, // Process uptime in seconds
pid: 1234, // Process ID
nodeVersion: "v20.0.0",
memoryUsage: 128, // Process memory in MB
cpuUsage: 2.5 // Process CPU usage %
}
}
Monitor database queries with Prisma middleware:
import { PrismaClient } from '@prisma/client';
import { prismaMiddleware, createPrismaHealthCheck } from 'vitals-node/prisma';
import { getMonitor } from 'vitals-node/core';
const prisma = new PrismaClient();
// Add middleware for query monitoring
prisma.$use(prismaMiddleware({
slowQueryThreshold: 1000, // Alert on queries > 1s
logSlowQueries: true
}));
// Add database health check
const monitor = getMonitor();
monitor.addHealthCheck(createPrismaHealthCheck(prisma));
Database metrics include:
Add your own health checks:
import { createMonitor } from 'vitals-node/core';
const monitor = createMonitor();
monitor.addHealthCheck({
name: 'redis',
critical: true,
timeout: 5000,
check: async () => {
const start = Date.now();
try {
await redis.ping();
return {
name: 'redis',
status: 'healthy',
responseTime: Date.now() - start,
message: 'Redis connection OK'
};
} catch (error) {
return {
name: 'redis',
status: 'unhealthy',
responseTime: Date.now() - start,
error: error.message
};
}
}
});
await monitor.start();
Subscribe to monitoring events:
import { getMonitor } from 'vitals-node/core';
const monitor = getMonitor();
// Subscribe to metrics collection
monitor.on('metrics:collected', (event) => {
console.log('Metrics:', event.data);
});
// Subscribe to alerts
monitor.on('alert:triggered', (event) => {
console.log('Alert!', event.data);
});
Available events:
metrics:collected - New metrics collectedalert:triggered - Alert threshold exceededalert:resolved - Alert condition resolvedhealth:changed - Health status changeddatabase:slow-query - Slow query detecteddatabase:error - Database error occurredThe /health/metrics endpoint exports Prometheus-compatible metrics:
# HELP vitals_cpu_usage_percent Current CPU usage percentage
# TYPE vitals_cpu_usage_percent gauge
vitals_cpu_usage_percent 45.5
# HELP vitals_memory_usage_percent Memory usage percentage
# TYPE vitals_memory_usage_percent gauge
vitals_memory_usage_percent 62.3
# ... more metrics
Add to your Prometheus config:
scrape_configs:
- job_name: 'my-app'
static_configs:
- targets: ['localhost:3000']
metrics_path: '/health/metrics'
The built-in dashboard provides:
Access at: http://your-server/health/dashboard
alerts: {
line: {
token: 'YOUR_LINE_NOTIFY_TOKEN',
enabled: true
}
}
alerts: {
telegram: {
botToken: 'YOUR_BOT_TOKEN',
chatId: 'YOUR_CHAT_ID',
enabled: true
}
}
alerts: {
email: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
user: 'your-email@gmail.com',
password: 'your-app-password',
from: 'alerts@yourapp.com',
to: ['admin@yourapp.com'],
enabled: true
}
}
import { expressPulse, createExpressRouter } from 'vitals-node/express';
// As middleware
app.use('/health', expressPulse(options));
// As router
const router = createExpressRouter(options);
app.use('/health', router);
import { NestPulseModule, PulseService } from 'vitals-node';
// In module
NestPulseModule.forRoot(options)
// Async configuration
NestPulseModule.forRootAsync({
useFactory: (configService) => ({
alerts: {
line: { token: configService.get('LINE_TOKEN') }
}
}),
inject: [ConfigService]
})
// Inject service
constructor(private pulseService: PulseService) {}
import { bunPulse, withBunPulse } from 'vitals-node/bun';
// Manual handler
const pulse = bunPulse(options);
pulse.handler(req);
// Wrapper
Bun.serve(withBunPulse({
...options,
fetch(req) {
return new Response('OK');
}
}));
import { createMonitor, getMonitor } from 'vitals-node/core';
const monitor = createMonitor(options);
await monitor.start();
// Get metrics
const metrics = await monitor.getMetrics();
const health = await monitor.getHealth();
const detailed = await monitor.getDetailedHealth();
// Prometheus export
const prometheusText = await monitor.getPrometheusMetrics();
// Dashboard HTML
const html = monitor.getDashboardHtml();
// History
const history = monitor.getHistory(3600000); // Last hour
// Stop
monitor.stop();
See the examples folder for complete examples:
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.
FAQs
Multi-framework health monitoring & system metrics for NestJS, Express, and Bun
The npm package vitals-node receives a total of 2 weekly downloads. As such, vitals-node popularity was classified as not popular.
We found that vitals-node demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.