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

nodepup

v3.0.13

Published

run tests with puppeteer and the nodejs test runner

Readme

Getting started

Run component tests in a real browser - without the hassle.

Why does this exist?

So we can test web components without compromise and without long feedback cycles.

  • simulated DOM environments (like JSDOM) don't (plan) to fully implement every Web API
  • e2e testing tools like cypress and/or playwright are too heavy handed - component testing is not their main focus

So this sits kind of in the middle between simulated, very fast tests and emulated but very slow tests.

Architecture

It is useful to understand what nodepup does differently under the hood so you can make informed decisions in your tests.

With simulated DOM environments (like jsdom) your tests run on the server and things like e.g. CSS will never be tested. Querying nodes and interacting with your components happens on the basis of a simulated environment which is fast but can only return stand-ins, which e.g. - at the time of writing - do not support form-associated custom elements.

Full e2e suites on the other hand start a headless browser and your test code also runs on the server. Your tests then execute a series of commands that are sent to that browser, meaning that interacting with elements is done either asynchronously or by injecting larger bits of code into the page and executing them there, creating a divide where server side code lives just a few lines away from client side code yet the two are completely separated contexts.

Nodepup takes a different approach: it bundles your tests with esbuild and serves that bundle via a small web server. Your tests run exclusively on the client and as such you can easily listen for events, assert the DOM structure synchronously and all that stuff.

This would however normally come with the same drawback however that a simulated environment has: user interactions can only be "faked". Libraries like user-event have been created to address this issue in a best-effort manner, but they can conceptually never reach the level of the e2e solutions.

For this reason nodepup enables user interactions by flipping the classical e2e approach on its head - instead of the server test code sending commands to the client the client test code tells the servere to execute the commands. While this might seem a like a roundabout way of doing things it has the benefit of combining the performance of a simulated environment with the capabilities of a real browser.

(Recommended) Usage

// Testbed.tsx
/**
 * This module exposes utility functions around testing.
 *
 * @module
 */
import { toHtml } from "tsx-to-html";
import * as Chai from "chai";
import chaiDom from "chai-dom";

Chai.use(chaiDom);

export const expect = Chai.expect;

export const render = (element: JSX.Element) => {
  // render the component to a plain HTML string.
  // You could also bootstrap your favorite framework here
  document.body.innerHTML = toHtml(element);

  return document;
};

export * from "@testing-library/dom";
export * from "nodepup";

// [...]

// MyComponent.test.tsx
import {
  describe,
  it,
  user,
  expect,
  render,
  getByRole,
  getCenterPoint,
  user,
} from "./Testbed.js";

describe("my component", () => {
  it("should match :hover when mouse hovers", async () => {
    // setup - could be abstracted on a "by component" basis
    const container = render(<my-input />);
    const input = getByRole(container, "textbox");

    // act
    const { x, y } = getCenterPoint(input); // util function from nodepup
    await user.mouse.move(x, y); // user tries to alias the puppeteer functions here

    // assert
    expect(input).to.match(":hover");
  });
});

Configuration

// nodepup.config.js

/**
 * @type import("nodepup/server").NodepupConfig
 */
export default {
  esbuild: {}, // changeable esbuild options
  coverage: {}, // changeable monocart-coverage-reporter options
  glob: "**/*.test.{ts,tsx}", // an extended glob to find your test files
  bodyContent: "", // html that replaces the document body before every test run
};

CLI Usage

See npx nodepup --help.