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

@lariocpt/crust

v0.3.3

Published

Mock it, test it, load it, tail it: the whole test stack baked into one binary. Spec-driven, generated, zero dependencies.

Readme

crust

Mock it, test it, load it, tail it: the whole test stack baked into one binary. Spec-driven, generated, zero dependencies.

Never reports a false pass — a run that measured nothing fails.

An OpenAPI mock server, fixture suites generated from the spec, load gates CI can fail on, a process orchestrator, and a link checker — every tool composes on the same | stream, driven from an interactive REPL, a crust -c one-liner, a .crust script, or as a one-shot command from your shell (crust mock-server openapi.yaml -p 4000).

npm i -g @lariocpt/crust

Documentation: https://lariocpt.github.io/crust-website/

Source and issues: https://github.com/lariocpt/crust

What it looks like

Lines below are parsed against the live grammar on every build, so an example that stopped working fails CI rather than misleading you.

Fixture tests — .crust.ts fixtures with setup() context and async matchers, JUnit for CI, and -n/-j to turn any fixture into a stress run:

test-fixture "tests/api/**/*.crust.ts" -j 8 -o reports/api.junit.xml
test-fixture tests/api/checkout.crust.ts -n 500 -j 32 -o reports/stress.json

Load testing with a gate CI can trust — thresholds are assert composition, and a run that measured nothing is refused rather than passing:

load 30s 200/s | parallel 50 | GET :3000/health | expect 200 | stats | assert (s => s.p95 < 250)
load 10s 50/s, 5m 200/s | parallel 200 | GET $BASE/api/search | stats --every 15 | assert (s => !s.window || s.p99 < 800)

A persistent mock server from a Swagger/OpenAPI spec — stateful CRUD persisted to sqlite so it survives a restart, seeded from a file, with spec-violating requests rejected as 422:

mock-server ./openapi.yaml -p 4010 --state ./.crust/mock.sqlite --seed seeds/dev.json --validate
{"thing": {"name": "x"}} | POST :4010/api/things | expect 201 | (r => r.json()) | capture TID (t => t.thing.id)

Point it at a real API instead and it audits that API's spec conformance:

mock-server ./swagger.json -p 4747 --proxy http://localhost:3001 --report violations.ndjson

SQL assertions, inline — rows stream one item each, and an empty result fails instead of passing quietly. The bind placeholder is ? for every dialect (crust rewrites it to $n for Postgres URLs):

sql "SELECT count(*)::int AS c FROM buildings WHERE name = 'Court'" | assert (r => r.c === 1)
sql "SELECT status FROM orders WHERE id = ?" $OID | assert (r => r.status === "paid")

Pretty logs from every service at once — procs merges stdout and stderr into one stream of {proc, stream, line} items, so you filter them as objects and hand the text to pino-pretty (local node_modules/.bin is on PATH):

procs({api: "bun run dev", worker: "bun run worker", db: "docker compose logs -f postgres"}) | (l => l.line) | pino-pretty --colorize
procs({api: "bun run dev", worker: "bun run worker"}) | filter (l => l.stream === "stdout") | (l => l.line) | pino-pretty --colorize --minimumLevel warn

Interactive log querying — logs holds one live stream and lets you iterate on filters against its buffered past and live future:

logs procs({api: "bun run dev", worker: "bun run worker"})
logs docker logs -f my-app

At its prompt each line runs over the buffer, then live until Ctrl-C:

logs> filter (l => l.proc === "api") | (l => l.line) | grep -i timeout
logs> json on
logs> filter (e => e.level >= 50) | stats --every 5
logs> search "connection reset"

Interactive shell

The REPL continues a line — a trailing \, an unbalanced quote, or an unclosed ( holds the line instead of erroring, so pasted multi-line JSON survives the Enter. Ctrl-R searches history; &, jobs, fg, bg, wait %N, kill %N and Ctrl-Z are job control. Scripts take positional arguments ($0, $1…, $#, $@), a bare FOO=x line persists for the session, and source runs .ts files, .crust scripts, and shell scripts alike.

MCP server

crust mcp speaks the Model Context Protocol over stdio, so an MCP-capable agent (OpenCode, Claude Code, Codex, Cursor) drives crust directly — every capability is a first-class tool, not a shell to fumble through. One-shot tools (crust_run_line, crust_test_fixture, crust_load_run, …) run a fresh crust process per call; lifecycle tools keep a mock server, a supervised procs runner, or a buffered logs session open across calls and tear them down honestly on exit. A nonzero run is always an isError result with the verbatim output — never a false pass.

{ "mcpServers": { "crust": { "command": "crust", "args": ["mcp"] } } }

The crust-mcp skill teaches an agent which crust_* tool fits which task.

Agent skills

Crust ships the SKILL.md guides that teach a coding agent how to drive it — pipelines, fixture suites, load gates, the mock server, procs, the log sessions, the link checker, the MCP server — embedded in the binary, so they always match the version you run. They go into .agents/skills/, the cross-client directory Codex, Cursor and OpenCode read, plus a link per skill in .claude/skills/ for Claude Code, the one mainstream host that doesn't read the standard path:

bunx crust skills install          # on a terminal: pick which ones
bunx crust skills install --all    # everything, into ./.agents/skills
bunx crust skills install --select crust-cli,crust-logs
bunx crust skills install --global # into ~/.agents/skills

The menu lists each skill with its status in the target it would write to (current, not installed, EDITED locally) and g switches between the project and ~/.agents/skills; declining exits 0. A .claude/skills/<name> directory crust did not write is left alone and reported — --force consents to replacing it with a link.

npm install asks once whether to install them. It never asks on CI, with piped output, for a global install, or once crust skills are already in the project under either path, and it can never fail the install. Answering no writes nothing; CRUST_NO_SKILLS=1 stops the question permanently.

What this package installs

This package is a ~4 KB launcher, not the binary. On first use it downloads the bun build --compile executable for your platform from the matching GitHub Release, verifies its published sha256 before the file is ever made executable, and caches it under ~/.cache/crust. Every install route resolves that same artifact.

What it installed is recorded in install-manifest.json next to package.json (plane, binary version, the package version that asked for it, the cached path and its sha256). Every run re-checks that the manifest was written for THIS package version on THIS plane: a version bump or a plane switch is a cache miss, so the launcher re-resolves, re-verifies the sha256 and rewrites the manifest — a stale install never shadows a new release, and no file has to be deleted by hand.

Supported platforms: linux x64/arm64, macOS x64/arm64. On anything else, build from source — see the repository README.

Environment variables

| Variable | Effect | |---|---| | CRUST_SOURCE | github (default for this package) or apps — which artifact plane to resolve from. | | CRUST_GITHUB_REPO | Override the owner/repo the release is fetched from. | | CRUST_APPS_URL | Base URL of a self-hosted artifact plane, used when CRUST_SOURCE=apps. | | CRUST_NO_SKILLS | Set to any value to stop the postinstall question about installing agent skills. crust skills install still works. |

MIT © Lario Borges