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

test-inventory

v0.6.0

Published

Test metadata from source code, not from test results.

Readme

Test metadata from source code, not from test results.

test-inventory reads Playwright and Vitest test files and lists every test declaration as JSON: its title, file and lines, the describes around it, its tags and annotations, and whether it is active, skipped, fixme, todo, expected to fail or in a file the runner refuses to load, with the condition when the state only applies sometimes. It parses the code and runs nothing, so it needs no browsers, no build and no runner configuration.

Documentation: huldoser.github.io/test-inventory

Install

npm install --save-dev test-inventory

Node.js 22.12 or newer, on Linux, macOS or Windows. Playwright 1.42 or newer, Vitest 3.0 or newer.

Command line

npx test-inventory "tests/**/*.spec.ts" --framework playwright --output inventory.json

Without the glob, the test files are those the Playwright or Vitest configs in the project run.

For this spec from a trading app's UI tests, tests/alerts.spec.ts:

import { test, expect } from '../fixtures/index';
import { isMarketClosed } from '../test-data/market-hours';

test.describe('price alerts', () => {
  test.skip(isMarketClosed(), 'Alerts only trigger while the market is open');

  test.beforeEach(async ({ alertsPage }) => {
    await alertsPage.goTo();
  });

  test('notifies when the price crosses above the alert', async ({ alertsPage }) => {
    await alertsPage.create('AAPL', 'above', 1);
    await expect(alertsPage.notifications).toContainText('AAPL is above $1.00');
  });

  // ...
});

the first test's record includes:

{
  "id": "006bcf2289191aef",
  "relativeFilePath": "tests/alerts.spec.ts",
  "lineStart": 11,
  "lineEnd": 14,
  "fullName": "price alerts > notifies when the price crosses above the alert",
  "state": "skip",
  "isConditional": true,
  "condition": "isMarketClosed()",
  "reason": "Alerts only trigger while the market is open",
  "stateSource": "suite",
  "tags": []
}

The output also has a summary with counts, a record for each describe, and diagnostics that point at code the scan could not read and values it could not work out. Filters such as --state skip, --tag @smoke and --grep "limit order" keep only some tests, --fields fullName,reason keeps only some keys, and --format jsonl writes one record per line.

Library

import { scan } from 'test-inventory';

const inventory = await scan({ patterns: ['tests/**/*.test.ts'], framework: 'vitest' });
const todo = inventory.tests.filter((test) => test.isTodo).map((test) => test.fullName);

scanSource() scans the code of one file without touching the disk. The JSON Schema of the output is exported as test-inventory/schema/v1.json, so a reader can pin the version of the format it understands.

AI agents

test-inventory-mcp is an MCP server built on test-inventory: agents in Claude Code, Cursor, VS Code and other MCP clients ask it which tests a project has without running them. The AI agents page has the setup and the other ways in.

Limits

  • Config files are read as code, never run, and only in part: settings computed at run time, as from process.env, can't be worked out, and settings such as workers or use are not read.
  • Values imported from other files are not worked out. A tag or title that comes from an import gets a diagnostic that names the module. A custom test object is followed through as many files as it takes, through relative paths, tsconfig path aliases, # imports in package.json and workspace packages; one that can't be followed gets an error. Tests declared in helper functions are listed at each call, also for helpers imported from other files.
  • A test in a loop or a .each table is one record, with isInLoop or caseCount; the runner creates one test per iteration or case.
  • Conditions such as browserName === 'webkit' are kept as source text, not evaluated.

Support

If test-inventory is useful to you, star it on GitHub or sponsor its development.

License

MIT, copyright © 2026 Andrey Rychkov.