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

mock-knight

v0.6.0

Published

A local-first web UI for HTTP mock servers

Readme

Mock Knight connects to a mock server you already run and helps you find a stub among thousands, understand why a request didn't match it, and change it safely on a server your whole team shares.

It is not a mock server. It never serves mock traffic. Point it at your WireMock or MockServer and it gives you a UI; stop it and your mocks carry on exactly as before.

npx mock-knight --url http://localhost:8080

Why

A mock server with three stubs needs no tool. A mock server with three thousand — shared by a team, edited by everyone, driving the tests that gate your release — is a different thing. The admin API answers questions one curl at a time, and the questions that actually matter are the ones it answers worst:

  • Which stub answered this request? And if none did, how close did each one get?
  • Which of these four stubs on /v1/rates actually wins? They differ only by a header.
  • Did my edit just silently drop a field the UI didn't know about?
  • Is this stub dead, or has it just not been called since the journal was last cleared?

What it does

| | | |---|---| | Find | Full-text and structured search (method:POST status:5xx header:X-Tenant), faceted filters with live counts, a folder tree, and a virtualised list that stays fluid at 10,000 rows | | Explain | For any unmatched request, the closest stubs ranked, with a field-by-field comparison of what matched and what didn't — and one click to create a stub that would have matched | | Priority | Which stub on a path actually answers, and which are shadowed. Invisible in a flat list, decisive on a corpus where stubs differ only by header | | Edit safely | Every write re-reads and hash-compares first, so two people editing the same stub get a three-way merge instead of a lost update | | Watch | A live request journal with match state, filters, and the match explainer one keystroke away | | Scenarios | Stateful stubs as a state graph, with unreachable states and dead ends flagged | | Keyboard first | ⌘K reaches every action, screen, server and stub; / focuses search; ? publishes the whole map | | Light and dark | Follows the OS by default, or pin either. It is a debugging tool; it gets used at both ends of the day |

Two principles shape all of it:

  • Your mock server is the source of truth. Mock Knight keeps a local SQLite mirror purely as a cache. Delete it and nothing is lost.
  • Nothing inferred is presented as fact. Anything Mock Knight worked out itself — overlap detection, ranked near-misses — is labelled as its own inference. Anything derived from the request journal carries the window it came from, because that journal is finite and resettable. A tool that presents a guess with the confidence of a fact gets abandoned the first time the guess is wrong.

Install

Requires Node 22 or newer (better-sqlite3 v13 needs it).

# one-off
npx mock-knight --url http://localhost:8080

# or keep it around
npm install -g mock-knight
mock-knight --url http://localhost:8080

It starts a local server, opens on http://127.0.0.1:7777, connects to the mock server you named, and mirrors its corpus.

Options

| Flag | Default | | |---|---|---| | --url <url> | — | Mock server to connect to on startup. A context path is kept: https://host/ctx calls https://host/ctx/__admin | | --port <n> | 7777 | | | --host <addr> | 127.0.0.1 | Anything else prints a warning — there is no authentication | | --state <path> | OS data dir | Where the SQLite mirror lives | | --name <name> | the URL's host | Profile name | | --no-refresh | | Skip the initial corpus mirror | | --mode <local\|deployed> | local | deployed disables actions that assume a single trusted user | | --config <path> | ./mock-knight.json if present | See below | | --no-config | | Ignore any config file |

Servers you connect to are remembered in the state database and stay in the list until you remove them (Servers → Remove). --url always decides which one the browser opens, whatever else is in there, and naming one that is already known simply opens it rather than adding a second copy.

One address, one server: two profiles reaching the same admin URL are refused, since both would mirror the same corpus and the switcher would offer a choice that changes nothing. The comparison is on the composed address, so a trailing slash or a spelled-out /__admin does not sneak a duplicate past.

mock-knight.json

Optional. Picked up from the working directory, or named with --config. A flag always wins over the file — a flag is what you typed just now.

{
  "$schema": "https://raw.githubusercontent.com/LamineMbn/mock-knight/main/schema/mock-knight.schema.json",
  "port": 7777,
  "state": "./mirror.db",            // relative to this file, not your shell's directory
  "allowedHosts": ["wiremock.internal:8080"],
  "profiles": [
    {
      "name": "staging",
      "adapter": "wiremock",
      "baseUrl": "${env:STAGING_MOCK_URL}",
      "authKind": "bearer",
      "authRef": "STAGING_TOKEN",     // the NAME of an env var, never a value
      "readOnly": true
    }
  ]
}
  • allowedHosts restricts where this instance may connect. Absent means no restriction; an empty array means nothing is reachable. Worth setting whenever you use --host.
  • profiles are reconciled by name on every start, so edit and restart. They are the way to share a set of servers with a team through version control.
  • ${env:VAR} is interpolated into string values, and refuses to start if the variable is unset rather than substituting an empty string. It is deliberately not applied to authRef, which names a variable rather than holding one — so a token cannot end up in a file you commit.
  • The $schema line gives you completion and validation in any editor that reads JSON Schema.
  • YAML is not implemented yet; a .yaml file is reported, not ignored.

Supported backends

| Backend | Status | |---|---| | WireMock 3.x | Supported. Read, write, journal, scenarios, near-miss | | WireMock 2.x | Read paths work; some admin routes are probed and gracefully absent | | MockServer | Supported. Read and write. No traffic log and no scenarios — it records no attribution for a served request and has no named states, so both screens are absent rather than empty | | Mockoon | Read-only. Its corpus is an environment JSON file — the admin API cannot read routes — so point a profile at the file. Traffic works where the admin token is set; editing is not offered yet, because Mockoon's only write does not reach the file | | Prism | Read-only. Its corpus is the OpenAPI document it serves — Prism has no control API — so point a profile at the file. An operation becomes one stub per declared response, ranked the way Prism picks: lowest 2xx first | | Hoverfly, JSON Server | Not yet. JSON Server in particular is a poor fit: it has no matchers, no journal and no stubs — its db.json holds data, and its routes are generated rather than declared |

Pick one with --adapter, or per server on the Servers screen:

npx mock-knight --url http://localhost:1080 --adapter mockserver

A Mockoon profile also needs the path to its environment JSON file — the Servers screen asks for it once Mockoon is chosen as the backend, because its admin API cannot read routes. Start Mockoon with --watch and the file is authoritative: edit it and the server follows.

mockoon-cli start --data ./env.json --port 3000 --watch --admin-api-token <token>

The traffic log needs that token; set it as an environment variable and name the variable in the profile's auth field, which is where every secret is referenced rather than stored.

Mock Knight probes each server on connect and derives a capability set. A capability that is off means the control is absent, never a button that fails when you press it. The Servers screen shows the full report and explains what each one being off costs you.

Security

Mock Knight is unauthenticated and binds to loopback by default. It is a developer tool for a machine you control.

  • It fetches arbitrary URLs by design, so an exposed instance is a relay into whatever network it can see. Binding to a non-loopback address prints a warning; put a reverse proxy in front of it if you must.
  • It never stores a secret. A profile holds the name of an environment variable, never its value. Nothing sensitive reaches the database, a log line, a URL, or the browser.
  • Configured headers are redacted before a request journal entry is stored.

Contributing

See CONTRIBUTING.md. It covers the layout, the four test tiers, and the architecture invariants — those are load-bearing, and a change that breaks one won't be merged even if the tests pass.

License

Apache-2.0 © Lamine Bendib