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

midnight-monitor

v1.0.1

Published

Midnight LLM Monitor for local LLM server hardware intelligence.

Readme

Midnight LLM Monitor

Midnight LLM Monitor is a lightweight hardware intelligence daemon for machines running local LLM servers such as Ollama, llama.cpp, and vLLM-adjacent tooling.

It exposes live metrics over REST and WebSocket so Midnight Coder can make decisions from real hardware state instead of guesses.

Current focus

  • GPU and VRAM visibility in the overview
  • Ollama running model CPU/GPU split, context usage, and model metadata
  • llama.cpp process discovery and model path/context hints
  • low-overhead polling with cached expensive collectors
  • plugin discovery for third-party collectors

Install

Requires Node.js 20 or newer.

npm install -g midnight-monitor

Run without installing:

npx midnight-monitor

Access

Start the daemon and open the dashboard in a browser:

midnight-monitor start

Then visit:

  • http://127.0.0.1:9898/ when the monitor runs on your own machine
  • http://<server-ip>:9898/ when the monitor runs on another host

The default HTTP port is 9898. If you change it in midnight-monitor.config.json, use that port instead.

CLI

midnight-monitor
midnight-monitor start
midnight-monitor stop
midnight-monitor status
midnight-monitor doctor
midnight-monitor benchmark

midnight-monitor without arguments prints help. Use midnight-monitor start to start the daemon.

Release

Releases are published from GitHub Actions, not from a local npm publish.

Prerequisites:

  • GitHub repository secret NPM_TOKEN must contain an npm automation token with publish access to midnight-monitor.
  • Commits merged to main must use Conventional Commits so semantic-release can decide the next version.

Publish flow:

npm run typecheck
npm run lint
npm test
npm run build
git push origin main

The Release workflow runs npx semantic-release, creates the GitHub release, and publishes the package to npm.

Configuration

Create midnight-monitor.config.json in the working directory.

{
  "server": {
    "host": "127.0.0.1",
    "port": 9898,
    "wsPath": "/ws"
  },
  "collectors": {
    "enabled": [
      "cpu",
      "ram",
      "swap",
      "gpu",
      "disk",
      "network",
      "temperatures",
      "processes",
      "ollama",
      "llamacpp",
      "history"
    ],
    "modules": []
  },
  "intervals": {
    "cpu": 1000,
    "ram": 1000,
    "swap": 1000,
    "gpu": 1000,
    "disk": 10000,
    "temperatures": 5000,
    "network": 1000,
    "processes": 1000,
    "ollama": 2000,
    "llamacpp": 2000,
    "history": 1000
  }
}

REST API

  • GET / dashboard web
  • GET /health
  • GET /metrics
  • GET /cpu
  • GET /memory
  • GET /swap
  • GET /gpu
  • GET /disk
  • GET /network
  • GET /ollama
  • GET /history
  • GET /processes

Example:

curl http://127.0.0.1:9898/metrics

WebSocket

Connect to /ws for live updates.

const socket = new WebSocket("ws://127.0.0.1:9898/ws");
socket.onmessage = (event) => {
  console.log(JSON.parse(event.data));
};

Web Monitor

Open http://127.0.0.1:9898/ to see the visual monitor with:

  • a GPU/VRAM-first overview for quick capacity checks
  • live CPU, RAM, swap, disk, network, and temperature cards
  • Ollama running models with CPU %, GPU %, context, context limit, and size
  • installed Ollama models with architecture and quantization
  • llama.cpp process detection with model path and context hints
  • top resource-consuming processes
  • history charts for recent pressure and speed changes
  • a gear menu for appearance settings
  • restore defaults for theme and layout
  • draggable and resizable widgets
  • warning, critical, and info analysis badges

Midnight LLM Monitor dashboard

Example payload

{
  "timestamp": "2026-07-17T12:00:00.000Z",
  "cpu": { "usage": 32, "cores": 8, "threads": 16, "frequencyMhz": 4300 },
  "ram": {
    "usedBytes": 123456789,
    "totalBytes": 17179869184,
    "usagePercent": 41.2
  },
  "swap": { "usedBytes": 0, "totalBytes": 34359738368, "usagePercent": 0 },
  "gpu": {
    "vendor": "AMD",
    "model": "Radeon RX 580",
    "usagePercent": 91,
    "temperatureCelsius": 72,
    "vram": {
      "usedBytes": 7488270336,
      "totalBytes": 8589934592,
      "freeBytes": 1101664256
    }
  },
  "ollama": {
    "running": [
      {
        "name": "midnightcoderagent/MidnightCoder-30B:latest",
        "cpuPercent": 59,
        "gpuPercent": 41,
        "context": 32768,
        "contextLength": 262144,
        "quantization": "IQ2_M",
        "architecture": "qwen3moe"
      }
    ],
    "installed": []
  },
  "llamacpp": { "running": [] },
  "analysis": [
    {
      "severity": "warning",
      "source": "gpu.vram",
      "message": "VRAM almost full. Model may spill into RAM."
    }
  ]
}

JSON Schemas

CpuMetrics

{
  "usage": "number",
  "cores": "number",
  "threads": "number",
  "loadAverage": "[number, number, number]",
  "frequencyMhz": "number",
  "uptimeSeconds": "number"
}

GpuMetrics

{
  "vendor": "string",
  "model": "string",
  "usagePercent": "number | null",
  "temperatureCelsius": "number | null",
  "vram": {
    "totalBytes": "number | null",
    "usedBytes": "number | null",
    "freeBytes": "number | null"
  }
}

Architecture

flowchart LR
  C[Collectors] --> M[Monitor Scheduler]
  M --> H[History Store]
  M --> A[Analysis Engine]
  M --> R[REST API]
  M --> W[WebSocket Stream]
  P[Plugin Packages] --> C

Collector plugins

Collectors are discovered from the built-in src/collectors/ directory and can also be loaded from installed npm packages.

Each collector implements:

initialize(context);
collect(context);
health();
dispose();

Third-party packages can export a createCollector-style factory and be enabled in midnight-monitor.config.json.

Contributing

  1. Fork or branch.
  2. Run npm install.
  3. Use npm run typecheck, npm run lint, and npm test.
  4. Keep collectors isolated and failure-tolerant.
  5. Include tests for parsing and analysis changes.
  6. If a change needs a new dependency, add it to package.json and update the lockfile before opening a PR.