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

@btravstack/testing

v0.39.0

Published

Test the applications @btravstack/core boots: an in-memory runtime, a fake clock, a boot fixture that stops what it started, and a tap into a running graph

Readme

@btravstack/testing

Test the applications @btravstack/core boots. A test.extend fixture that starts a module with a test's defaults and stops every app it started when the test ends, a tap that hands back the very services a booted graph holds, an in-memory runtime, a clock that moves on demand — the way @nestjs/testing is to NestJS, and kept out of the kernel so a production bundle never pulls the fakes in.

📖 Documentation · Reference · API Reference

pnpm add -D @btravstack/testing @btravstack/core @btravstack/config @btravstack/di unthrown

@btravstack/core, @btravstack/config, @btravstack/di and unthrown are peer dependencies; the package depends on nothing else — not even vitest: bootFixture is a plain (ctx, use) => Promise<void> function, which is vitest's fixture protocol, so no import is needed to hand it to test.extend. jose is an optional peer behind the @btravstack/testing/jwt subpath — see below — so a consumer that never imports it installs nothing extra. Node >=22.

A booted application, as a fixture

import { bootFixture, tapped, type Boot } from "@btravstack/testing";
import { expect, test } from "vitest";

const it = test.extend<{ boot: Boot }>({
  boot: bootFixture({ env: { PORT: "0", HOST: "127.0.0.1" } }),
});

it("serves on an ephemeral port", async ({ boot }) => {
  const app = boot(OrderApi);

  await expect(app.runtimeInfo()).toBeOkWith(
    expect.objectContaining({ port: expect.any(Number) }),
  );
});

it("holds the very logger the use cases write to", async ({ boot }) => {
  const tap = tapped(OrderApi, [Logger]);
  await boot(tap.module).runtimeInfo();

  const [logger] = tap.services();
  expect(logger.lines()).toEqual([]);
});

boot is start as a test hands it out: the same signature, the same compile-time gate, minus signals — always off — with probes: false unless a call asks for a port, preDrainDelayMs: 0 and a silent onEvent as defaults, each overridable by the fixture's defaults and again per call. When the test ends every app it started is stopped, on every exit path, a failing assertion included; a Defect on exited fails the test even when the test never looked at it, while a modeled Err — a startup failure the test may be asserting — passes through.

tapped(module, [Port, …]) composes one more provider around module, depending on those ports, and remembers what it was built with: services() answers the very instances the running graph holds once it is built — after runtimeInfo() resolves, say — and throws before. The gate refuses a port module does not export.

What it ships

  • bootFixture(defaults?) — the fixture above; Boot and BootDefaults are its types.
  • tapped(module, ports) → { module, services() } — read services out of a booted application.
  • testRuntime(name?, { unit? }) / TestRuntimePort — an in-memory Runtime with submit() to hold a unit open across a drain, host() to reach the RuntimeHost it was last started with, and a module that provides it where a starter would; unit is a module every submitted unit forks, with no seed, before its work runs — and what that module needs joins module's own, so start names it instead of the first submit() failing.
  • overridden(module, [providers]) — substitute named providers into your real composition root, rather than maintaining a parallel test root beside it. It replaces one provider, never a subsystem: the replaced provider's siblings still construct, so swapping a whole adapter stack is still a different module composed in its place. An override for a port the tree stopped providing is a WiringDefect ("nothing to override"), which is what keeps a test root from drifting silently away from the real one — the drift that four hand-maintained parallel roots had already produced here. overridden(module, [providers], { unit: { user: [providers] } }) reaches inside a unit module the root binds, by kind, with the same drift gate at boot.
  • createFakeClock(start?) — a Clock for StartOptions.clock whose time moves only on advance(ms).

The teardown rule: a Defect on exited fails the test, a modeled Err does not.

A local JWT issuer, on its own subpath

import { localIssuer } from "@btravstack/testing/jwt";

const issuer = await localIssuer({
  issuer: "https://issuer.test",
  audience: "orders-api",
}).get();

const token = await issuer.sign({ sub: "u-1" }).get();
// verify `token` against `issuer.jwks`, the same way a real JWKS would be
await issuer.close();

@btravstack/testing/jwt's localIssuer(options) mints a generated key pair, a node:http listener answering its public key as a JWKS, and a sign(claims?, options?) closing over the private key — a real fetch against a real JWKS document, for a test that wants the verifying library's own behaviour rather than a double's. sign's expiresIn: false mints a token with no exp claim, and the key is RS256. The subpath needs Node ≥22.12 under CommonJS — jose is ESM-only, so the CJS build's require("jose") depends on require(esm); ESM consumers, and anyone who never imports the subpath, are unaffected.

License

MIT © Benoit TRAVERS