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

inertion

v0.2.3

Published

`inertion` is a testing library that aims to be **simple** and **safe**.

Readme

inertion is a testing library that aims to be simple and safe.

It tries to honor the Go language philosophy of testing - paraphrasing:

testing frameworks tend to develop into mini-languages of their own, with conditionals and controls and printing mechanisms, but JavaScript already has all those capabilities; why recreate them? We'd rather write tests in JavaScript; it's one fewer language to learn and the approach keeps the tests straightforward and easy to understand.

Unlike most test libraries, this one is not a framework - it does not automatically collect your tests, run your tests, print results to the console, or do anything else. This is a library - it doesn't do anything unless you call up it's functions.

Most test frameworks heavily rely on global state and side effects - things you wouldn't accept in the code you're testing. Why don't we have the same expectations for our testing tools? Because there is no shared state - because everything is literally just functions - this library can even reliably test itself, with no workarounds.

The test harness very small, and everything else is optional - the core of the package is mostly types that define generic relationships between assertions, tests and their dependencies, and the results.

The package is fully self-contained (no dependencies) but internally bundles the following popular packages, all of which have 30M+ downloads per week:

Installation

Node 16+, CommonJS or ES6:

npm install inertion

Under Node, you can use ts-node to run tests directly. You can use nyc for code-coverage. Have a look at scripts and devDependencies in package.json of this project for reference.

In Deno and modern browsers, you can use vanilla ES6 import from a CDN:

import { setup, run } from "https://esm.sh/inertion";

What do reports look like?

Arguably, the most important part of the developer experience when testing, is what happens when your tests fail - a lot of time was invested here, and the built-in reporter has a number of different layouts for different conditions, based on actual and expected values and types.

The output is minimally color-coded with errors highlighted in red, and the required corrections highlighted in green - here are some examples:

image

What do tests look like?

A minimal test module calls setup and uses the resulting test function to add tests:

hello.test.ts

import { setup, assertions } from "inertion";

export const test = setup(assertions);

test(`hello world`, async is => {
  is.ok(true, "all good");
  is.equal(1, 2, "oh no, so wrong");
});

What does an entry script look like?

A minimal test script will run the tests, and then most likely exit with statusOf(results):

import { run, printReport, statusOf } from "inertion";
import test from "./hello.test.ts";

(async () => {
  const results = await run(test);

  printReport(results);

  process.exit(statusOf(results));
})();

Do I have to manually import each test?

Under Node.JS, you can use e.g. fast-glob or any library of your choice to automatically locate your tests - adding this to your entry-script is literally two lines of code:

import { run, printReport, statusOf } from "inertion";
import { test } from "./test/harness.js";
import glob from "fast-glob";
import process from "process";

(async () => {
  const files = glob.sync("**/*.test.ts", { absolute: true });

  await Promise.all(files.map(file => import(file)));

  const results = await run(test);

  printReport(results);

  process.exit(statusOf(results));
})();
Why isn't this just built-in?
  • Because it's already easy, if you want it.
  • Owning this bit of code gives you control over paths, filename conventions, etc.
  • The library is intended to work in the browser - glob doesn't work in browsers.
  • This allows you to use multiple test-harnesses with different assertions, context, etc.

What if your tests have common dependencies?

You can provide a context factory to setup - every test will receive a new context from your factory function:

import { setup, assertions } from "inertion";

export const test = setup(assertions, () => ({
  get testSubject() {
    return new TestSubject("abc", [1,2,3]);
  }
}));

test(`hello world`, async (is, { testSubject }) => {
  is.ok(testSubject instanceof TestSubject, "all good");
});

What are the built-in assertions?

The core philosophy of this package, is to have as few assertions as absolutely necessary - for the most part, you will use ok and equal and familiar language constructs, rather than an arsenal of assertions to replace those language constructs.

You can easily inject your own assertions - the library provides the following by default:

is.ok(value)                    // value must strictly === true
is.notOk(value)                 // value must strictly === false

is.equal(actual, expected)      // deep equality test (using e.g. `fast-deep-equal` etc.)
is.notEqual(actual, expected)   // deep non-equality

is.same(actual, expected)       // strict sameness test (using `Object.is`)
is.notSame(actual, expected)    // strict non-sameness

is.passed()                     // manually pass a test
is.failed()                     // manually fail

With every assertion, you can optionally provide additional details after the required arguments - and it is considered best practice to at least include a string to explain why the assertion should pass.

How to test for expected exceptions?

Sticking to the philosophy of use the language, is.passed and is.failed should be used to test for expected exceptions - the pattern is very simple:

test(`something`, async is => {
  try {
    await thisShouldThrow();

    is.failed("oh no, it didn't throw!");
  } catch (e) {
    is.ok(error.message.includes("words"), "it should throw!");
  }
});

(The benefit of using this pattern, is it works with async and await and survives refactoring between async and non-async, without having to switch between different assertions.)

Why should I care?

This library is very open-ended - there are almost no decisions baked-in.

  • Want different assertions? Provide your own assertion functions to setup.
  • Need some test helpers or mocks or whatever? Use context factory-functions.
  • Have different tests with different needs? Create as many test functions as needed, with different assertions and context functions.

Have any other special needs?

This is truly just a library: assertions, reporters and test-runners are just functions - use as much or as little as you need, import from third-party libraries, or write your own.