Real-time system monitor for Node.js β CPU, RAM, Disk, Network, Battery & more.
Zero dependencies. Works on Linux, macOS, Windows, Android (Termux) and BSD.
Developed by Crystal Studio Labs Β Β·Β Author SahooShuvranshu
π Total Visitors | π Repo Traffic
npm install @crystal-studio-labs/crystalsystem.jsThat's it. No external packages are installed β it uses only Node.js built-ins.
Drop this into any Node.js file and run it:
const { crystalsystem } = require('@crystal-studio-labs/crystalsystem.js');
crystalsystem();Your terminal will show a live dashboard that refreshes every 5 seconds.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CRYSTAL SYSTEM.JS v1.0.3 SYSTEM INFORMATION β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ PLATFORM ββββββββββββββββββββββββββββββββββββββββββββββ
β OS Android 12 (aarch64) β
β Hostname localhost β
β Uptime 3h 22m 10s β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ CPU ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Model Qualcomm Snapdragon 8 Gen 1 β
β Cores 8 threads β
β Usage ββββββββββββββββββββ 42% ββββ
ββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ MEMORY βββββββββββββββββββββββββββββββββββββββββββββββββ
β Total 8 GB β
β Used 3.4 GB (42.50%) β
β Free 4.6 GB β
β Usage ββββββββββββββββββββ 42% βββββ
βββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ NETWORK ββββββββββββββββββββββββββββββββββββββββββββββββ
β Total β 1.2 GB β
β Total β 340 MB β
β Speed β 1.4 MB/s β
β Speed β 220 KB/s β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
You can customize everything by passing an options object:
const { crystalsystem } = require('@crystal-studio-labs/crystalsystem.js');
crystalsystem({
interval: 5000, // How often to refresh in milliseconds (default: 5000)
clearConsole: true, // Clear the terminal before each refresh (default: true)
showColors: true, // Show colored output (default: true)
showNetwork: true, // Show network section (default: true)
showDisk: true, // Show disk section (default: true)
showBattery: true, // Show battery section (default: true)
showGPU: true, // Show GPU section (default: true)
showProcesses: true, // Show top processes section (default: true)
historySize: 30, // How many data points to keep for sparklines (default: 30)
// Optional: save stats to a file
logFile: 'stats.json',
// Optional: start a live JSON API server
httpPort: 3001,
// Optional: get notified when usage is too high
thresholds: {
cpu: 90, // Alert when CPU is over 90%
memory: 85, // Alert when RAM is over 85%
disk: 90, // Alert when Disk is over 90%
},
});Get notified automatically when your system is under pressure:
const { CrystalSystem } = require('@crystal-studio-labs/crystalsystem.js');
const cs = new CrystalSystem({
interval: 3000,
thresholds: {
cpu: 80,
memory: 75,
disk: 90,
},
});
// This fires whenever a threshold is exceeded
cs.on('alert', ({ type, message, value, threshold }) => {
console.log(`β οΈ ALERT [${type}] β ${message}`);
// You can send a Discord message, restart a process, write a log, anything.
});
cs.start();Listen to every tick of data β useful for building your own integrations:
const { CrystalSystem } = require('@crystal-studio-labs/crystalsystem.js');
const cs = new CrystalSystem({ interval: 2000 });
cs.on('data', (stats) => {
console.log('CPU usage :', stats.cpu.loadPercent);
console.log('RAM usage :', stats.memory.percent);
console.log('Download :', stats.network.rxSpeed);
console.log('Upload :', stats.network.txSpeed);
});
cs.start();
// Stop the monitor after 30 seconds
setTimeout(() => cs.stop(), 30_000);The stats object contains everything β platform, CPU, memory, network, disk, battery, GPU, and top processes.
Start a live JSON API that any browser, app, or tool can query:
const { crystalsystem } = require('@crystal-studio-labs/crystalsystem.js');
crystalsystem({ httpPort: 3001 });Now open your browser or use curl:
curl http://localhost:3001/
curl http://localhost:3001/cpu
curl http://localhost:3001/memory
curl http://localhost:3001/network
curl http://localhost:3001/disk
curl http://localhost:3001/battery
curl http://localhost:3001/healthEvery response is JSON. Great for wiring into Grafana, Discord bots, web dashboards, or any monitoring setup.
Save a history of your system stats to a file automatically:
const { crystalsystem } = require('@crystal-studio-labs/crystalsystem.js');
crystalsystem({
logFile: 'stats.json',
interval: 10_000, // Log every 10 seconds
});Or write and read logs manually:
const { createLogger, getAllStats } = require('@crystal-studio-labs/crystalsystem.js');
const logger = createLogger('stats.json');
// Save a snapshot right now
logger.write(getAllStats());
// Read all saved snapshots back
const history = logger.readAll();
console.log(`Saved ${history.length} entries`);
// Find the highest CPU spike ever recorded
const peakCPU = Math.max(...history.map(s => s.cpu.loadRaw));
console.log(`Peak CPU: ${peakCPU}%`);Each entry is one JSON line in the file β easy to read, grep, or import anywhere.
Use any function on its own without starting a monitor:
const {
getCPUInfo,
getMemoryInfo,
getNetworkInfo,
getDiskInfo,
getBatteryInfo,
getGPUInfo,
getTopProcesses,
getAllStats,
formatBytes,
} = require('@crystal-studio-labs/crystalsystem.js');
// CPU
const cpu = getCPUInfo();
console.log(cpu.model); // "Qualcomm Snapdragon 8 Gen 1"
console.log(cpu.cores); // 8
console.log(cpu.loadPercent); // "42.50%"
// Memory
const mem = getMemoryInfo();
console.log(mem.total); // "8 GB"
console.log(mem.used); // "3.4 GB (42.50%)"
// Network
const net = getNetworkInfo();
console.log(net.rxSpeed); // "1.4 MB/s"
console.log(net.txSpeed); // "220 KB/s"
// Top 5 processes by memory
const procs = getTopProcesses(5);
procs.forEach(p => {
console.log(`${p.name} β CPU: ${p.cpu} RAM: ${p.mem}`);
});
// Everything at once
const all = getAllStats();
console.log(all.platform.platformName); // "Android"
console.log(all.disk.total); // "128 GB"
// Format any byte number
console.log(formatBytes(1_073_741_824)); // "1 GB"Install globally to get the crystalsystem command:
npm install -g @crystal-studio-labs/crystalsystem.jsThen run it anywhere:
# Live dashboard
crystalsystem
# Refresh every 2 seconds
crystalsystem -i 2
# Show once and exit
crystalsystem --once
# Get a raw JSON snapshot
crystalsystem --json
# Start with HTTP API and file logging
crystalsystem -p 3001 -l stats.json
# Hide sections you don't need
crystalsystem --no-gpu --no-battery --no-disk
# Show all available flags
crystalsystem --help| Flag | Short | What it does |
|---|---|---|
--help |
-h |
Show help |
--once |
-o |
Show dashboard once and exit |
--json |
-j |
Print JSON snapshot and exit |
--interval <sec> |
-i |
Refresh every N seconds |
--port <port> |
-p |
Start HTTP API on this port |
--log <file> |
-l |
Save stats to a JSON log file |
--no-color |
Turn off colors | |
--no-network |
Hide network section | |
--no-disk |
Hide disk section | |
--no-battery |
Hide battery section | |
--no-gpu |
Hide GPU section | |
--no-processes |
Hide top processes | |
--no-clear |
Don't clear screen between updates |
Full type definitions are included β no @types package needed:
import crystalsystem, {
CrystalSystem,
CrystalSystemOptions,
SystemStats,
AlertEvent,
CPUInfo,
MemoryInfo,
} from '@crystal-studio-labs/crystalsystem.js';
const options: CrystalSystemOptions = {
interval: 3000,
thresholds: { cpu: 80, memory: 80 },
};
const cs: CrystalSystem = crystalsystem(options);
cs.on('data', (stats: SystemStats) => {
const cpu: CPUInfo = stats.cpu;
const mem: MemoryInfo = stats.memory;
console.log(cpu.loadPercent, mem.percent);
});
cs.on('alert', (alert: AlertEvent) => {
console.error(`[${alert.type.toUpperCase()}] ${alert.message}`);
});| Function | Description |
|---|---|
crystalsystem(options?) |
Start the live dashboard. Returns a CrystalSystem instance. |
new CrystalSystem(options?) |
Create an instance manually. Call .start() when ready. |
buildSystemTable(options?) |
Get the full dashboard as a string β no loop started. |
getAllStats(options?) |
Get all system stats as one object β no display. |
startHttpServer(port?, options?) |
Start the HTTP API server on its own. |
createLogger(filePath) |
Create a file logger for saving stats. |
getCPUInfo() |
CPU model, speed, cores, real usage %. |
getMemoryInfo() |
Total, used, free memory. |
getNetworkInfo() |
Traffic totals and live speed. |
getDiskInfo() |
Disk partitions, total, used, free. |
getBatteryInfo() |
Battery level and charging status. |
getGPUInfo() |
GPU model where available. |
getProcessInfo() |
PID, Node.js version, heap memory. |
getTopProcesses(limit?) |
Top N processes sorted by memory. |
formatBytes(bytes, decimals?) |
Convert bytes to a readable string like "1.5 GB". |
sparkline(history, width?) |
Generate a sparkline string from an array of numbers. |
| Method | Description |
|---|---|
.start() |
Start the monitor. |
.stop() |
Stop the monitor and shut down HTTP server if running. |
.display() |
Render and print the dashboard once right now. |
.snapshot() |
Get a one-time snapshot of all stats. |
.setThreshold(type, value) |
Change an alert threshold while running. |
.on('data', fn) |
Listen to every stats update. |
.on('alert', fn) |
Listen to threshold alerts. |
.on('stop', fn) |
Fires when the monitor stops. |
| Platform | CPU | Memory | Disk | Network | Battery | GPU |
|---|---|---|---|---|---|---|
| π§ Linux | β | β | β | β | β | β |
| π€ Android / Termux | β | β | β | β | β | β |
| π macOS | β | β | β | β | β | β |
| πͺ Windows | β | β | β | β | β | β |
| π FreeBSD / OpenBSD | β | β | β | β | β | β |
Battery and GPU on Windows are not yet supported.
Does this slow down my app? No. It reads from OS APIs that are already available β no extra processes are spawned unless you use GPU or battery detection on specific platforms.
Can I use it in production?
Yes. Set interval: 0 to get a one-shot snapshot, or use the event emitter API to integrate with your own logging or alerting system without showing the dashboard.
Does it work on Termux (Android)?
Yes. It falls back to /proc/cpuinfo when Android restricts os.cpus(), so CPU info still works correctly.
Can I send the stats somewhere?
Yes β use cs.on('data', fn) to receive every update and do whatever you want with it: send to a database, post to a webhook, broadcast over a WebSocket, etc.
---
MIT β Β© Crystal Studio Labs Β· SahooShuvranshu