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

termiwatch

v1.0.1

Published

Zero-config, one-line terminal dashboard for Node.js apps. Real-time CPU, memory, event loop, HTTP metrics, and logs.

Readme

Why termiwatch?

Most Node.js monitoring tools are either dead, heavy, or require external services:

| Tool | Status | Dependencies | Setup | |------|--------|-------------|-------| | nodejs-dashboard | Archived (2022) | blessed, socket.io | Global install + wrapper | | clinic.js | Dead (3 years) | Native compilation | CLI profiling sessions | | appmetrics-dash | Dead (6 years) | C++ native addon | Code changes + browser | | PM2 monit | Active | Entire PM2 ecosystem | Full process manager | | termiwatch | Active | Zero | One line |

termiwatch gives you Datadog-level metrics in your terminal with zero setup:

  • One lineimport "termiwatch/auto" and you're done
  • Zero dependencies — custom ANSI renderer, no native addons, nothing to break
  • 14 metric categories — CPU, memory, event loop, GC pauses, heap spaces, HTTP, network I/O, DNS, worker threads, and more
  • 5 dashboard views — Tab to cycle between Overview, Memory, HTTP, Network, and Logs
  • Production safe — unref'd timers, TTY detection, alt-screen buffer
  • 428 KB total package size

Quick Start

Install

npm install termiwatch

Use (pick one)

Option 1 — One line (recommended)

import "termiwatch/auto"

// ... your app code below. That's it.

Option 2 — CLI wrapper (zero code changes)

npx termiwatch server.js

Option 3 — Manual API

import { startTermiwatch, stopTermiwatch } from "termiwatch"

const nw = startTermiwatch({ refreshInterval: 500 })

// Later...
const metrics = nw.collectMetrics()
stopTermiwatch()

Dashboard Views

Press Tab to cycle between views, Shift+Tab to go back.

1. Overview

Everything at a glance — CPU and memory with braille-resolution sparklines, event loop delay + ELU, GC pause tracking, HTTP req/s, handle leak detection, and live logs.

2. Memory & GC

Deep-dive into memory — full-width braille chart, per-heap-space breakdown (new/old/code/large object), GC pause detail by kind (minor/major/incremental), and a handle leak monitor with trend detection.

3. HTTP

Request throughput — large braille chart of req/s over time, per-status-code breakdown with bars, event loop health, and CPU usage.

4. Network & Workers

Network I/O — active TCP sockets with bytes read/written, DNS lookup timing, worker thread monitoring (per-thread ELU and heap), and async activity levels.

5. Logs

Full-screen log viewer — all captured stdout/stderr/errors with timestamps, color-coded by type, with stats bar.

What It Tracks

| Category | Metrics | Source | |----------|---------|--------| | CPU | Usage %, user/system split, history | process.cpuUsage() | | Memory | RSS, heap used/total, external, array buffers | process.memoryUsage() | | Event Loop | Mean delay, p99, min, max | perf_hooks.monitorEventLoopDelay() | | ELU | Event loop utilization (0-100%) | performance.eventLoopUtilization() | | GC | Pause count, avg/max duration, frequency, kind | PerformanceObserver({ entryTypes: ['gc'] }) | | Heap Spaces | Per-space size/used/available (new, old, code...) | v8.getHeapSpaceStatistics() | | Handles | Active count, by type, leak trend | process._getActiveHandles() | | HTTP | Req/s, total, active, avg latency, status codes | Monkey-patches http.createServer | | Network | Active sockets, bytes read/written, socket table | Socket stats from active handles | | DNS | Lookup timing, average resolution time | PerformanceObserver({ entryTypes: ['dns'] }) | | Workers | Per-thread ELU, heap used/total, status | worker.performance.eventLoopUtilization() | | Async | Active handles count, pending I/O requests | process._getActiveHandles/Requests() | | Framework | Auto-detect Express, Fastify, Koa, Hapi, NestJS, Next | require.cache inspection | | Runtime | Detect nodemon, PM2, tsx, ts-node, --watch, Bun, Deno | Environment variable checks |

Auto-Detection

termiwatch automatically detects your framework and runtime environment — no config needed.

Frameworks: Express, Fastify, Koa, Hapi, NestJS, Next.js

Runtimes: nodemon, PM2 (with instance ID and cluster mode), tsx, ts-node, node --watch, Bun, Deno

Detected framework and runtime are shown as badges in the dashboard header:

⚡ termiwatch │ ● RUNNING │ PID 1234 │ v20.10.0 │ ↑ 2h │ express 4.21.0 │ nodemon

API Reference

startTermiwatch(config?)

Start monitoring and return the Termiwatch instance.

const nw = startTermiwatch({
  refreshInterval: 1000,  // ms between updates (default: 1000)
  historySize: 60,        // data points for sparklines (default: 60)
  patchHttp: true,        // track HTTP requests (default: true)
  patchConsole: true,     // capture console output (default: true)
  showDashboard: true,    // render terminal UI (default: true)
})

stopTermiwatch()

Stop monitoring, restore console, clean up.

stopTermiwatch()

getTermiwatch()

Get the singleton instance (useful when using termiwatch/auto).

import "termiwatch/auto"
import { getTermiwatch } from "termiwatch"

const nw = getTermiwatch()
const metrics = nw.collectMetrics()

nw.collectMetrics()

Returns a complete Metrics snapshot:

const m = nw.collectMetrics()

console.log(m.cpu.usage)              // 12.4
console.log(m.memory.heapUsed)        // 29360128
console.log(m.eventLoop.p99)          // 2.31
console.log(m.eventLoop.utilization)  // 0.08
console.log(m.gc.maxPauseMs)          // 12.1
console.log(m.http.requestsPerSecond) // 847
console.log(m.network.activeSockets)  // 3
console.log(m.workers.count)          // 2
console.log(m.handles.trend)          // 'stable'
console.log(m.process.framework)      // 'express'

nw.getLogs()

Returns captured log entries:

const logs = nw.getLogs()
// [{ timestamp: 1711234567890, message: 'Server started', type: 'stdout' }, ...]

CLI Usage

# Run any Node.js script with the dashboard
npx termiwatch server.js

# Pass arguments through
npx termiwatch app.js --port 3000 --env production

# Help
npx termiwatch --help

The CLI wrapper uses --require to preload termiwatch before your code runs — zero modifications needed.

Headless Mode

Use termiwatch for metrics collection without the dashboard:

import { startTermiwatch } from "termiwatch"

const nw = startTermiwatch({ showDashboard: false })

setInterval(() => {
  const m = nw.collectMetrics()
  // Send to your own monitoring, logging, or alerting system
  myLogger.info('metrics', {
    cpu: m.cpu.usage,
    memory: m.memory.heapUsed,
    eventLoopP99: m.eventLoop.p99,
    gcMaxPause: m.gc.maxPauseMs,
    rps: m.http.requestsPerSecond,
  })
}, 5000)

termiwatch also skips the dashboard automatically in non-TTY environments (CI, piped output, Docker logs).

How It Works

termiwatch uses only Node.js built-in APIs — no native addons, no external processes:

  • Terminal UI: Custom ANSI escape code renderer with Unicode box-drawing characters and braille sparklines (U+2800-U+28FF) for 8x resolution charts
  • HTTP tracking: Monkey-patches http.createServer using the same APM technique as Datadog and New Relic
  • Console capture: Wraps process.stdout.write (not console.log) to preserve stack traces
  • Worker monitoring: Intercepts the Worker constructor via Module._load + Proxy to track threads from the main thread
  • Production safety: All timers call .unref(), dashboard renders in alt-screen buffer, TTY detection prevents rendering in CI

Requirements

  • Node.js >= 16.0.0
  • A terminal with Unicode support (virtually all modern terminals)

FAQ

Minimal impact. Metrics collection uses Node.js built-in APIs (process.cpuUsage(), perf_hooks, v8 module) which are designed for production use. The HTTP monkey-patch adds ~0.01ms per request. The dashboard renders in an alt-screen buffer on a 1s interval with change detection to avoid unnecessary writes. All timers are .unref()'d so termiwatch never keeps your process alive.

Yes. Use showDashboard: false in production to collect metrics without the terminal UI. The dashboard auto-disables in non-TTY environments (Docker, CI, piped output).

No. termiwatch wraps process.stdout.write (not console.log directly), so stack traces, source locations, and debugger integration are preserved. When the dashboard is visible, console output is captured and shown in the Logs panel. When the dashboard exits, original behavior is restored.

Yes. termiwatch auto-detects your framework and patches http.createServer at the Node.js level, so it works with any framework that uses Node's built-in HTTP server — which is all of them.

Yes. termiwatch intercepts the Worker constructor and monitors each thread's event loop utilization and heap usage from the main thread — no code changes in your workers needed. Just make sure termiwatch is imported before worker_threads.

Yes. termiwatch detects these runtimes automatically and shows them in the dashboard header. For PM2, it shows the instance ID and cluster mode.

License

MIT