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

ripplo

v0.9.4

Published

CLI for Ripplo — AI-powered end-to-end testing

Readme

ripplo

Describe how your app should behave. Ripplo proves it does.

You declare your app's state model and user flows in TypeScript. Ripplo seeds real data, drives a real browser, and checks the result against the model: the UI you asserted on and the rows that should have changed underneath it.

export const createTask = test("Create a task", () => {
  const { me, project } = ownedProject();
  return {
    given: [me, project],
    steps: [
      goto`/projects/${project.id}/tasks`.expect(visible(button("New"))),
      click(button("New")).expect(visible(textbox("Title"))),
      fill(textbox("Title"), "Buy milk"),
      click(button("Create")).expect(Task.created({ title: "Buy milk", projectId: project.id })),
    ],
  };
});

ownedProject() describes the starting state; Ripplo seeds it fresh for every run. Task.created(...) is checked against your actual database through a small engine you write once per entity.

Setup with Claude Code

If you use Claude Code, this is the shortest path. One command installs the plugin and opens a guided session that handles auth, project creation, scaffolding, and adapter wiring, and adds hooks that keep tests in sync as the agent changes your code.

npx ripplo setup

Skip the rest of this section unless you want to know what setup does, or you're not on Claude Code.

Setup by hand

Three steps: authenticate, scaffold, mount the engine adapter in your app server.

npx ripplo auth login   # device-code flow, opens a browser
npx ripplo init         # scaffolds .ripplo/ and writes RIPPLO_* env vars

ripplo init creates .ripplo/ (entities, worlds, tests, plus a project.json), appends RIPPLO_APP_URL, RIPPLO_ENGINE_URL, and RIPPLO_WEBHOOK_SECRET to your env file, and installs @ripplo/testing.

Then mount the adapter. This is the one piece of code that lives in your app: a signed-webhook endpoint Ripplo calls to seed and read state, active only when you flip the env var.

// Express
import { createEngineHandler } from "@ripplo/testing/express";
import { engine } from "./test/engine.js";

app.use(
  "/ripplo",
  createEngineHandler({ enabled: process.env.ENABLE_RIPPLO_TESTING === "true", engine }),
);

engine is where you implement seed and read for each entity you declared; TypeScript flags any entity you forgot. More framework adapters are coming; any server that can mount an Express router works today.

Last, preload @ripplo/instrument in your dev server so test runs capture your backend spans alongside browser actions:

node --import @ripplo/instrument server.js   # or NODE_OPTIONS="--import @ripplo/instrument" next dev

It exports spans to the local daemon during runs and stays dormant otherwise, so it's safe to leave in your dev script permanently.

Running tests

Start the daemon in one terminal and leave it running next to your dev server:

npx ripplo daemon

It keeps a warm browser pool and executes runs in parallel as they come in. Then:

npx ripplo run            # tests in scope + tests affected by your changes
npx ripplo run --all      # everything
npx ripplo run my-test    # one test by id

run connects to the daemon and streams results; if a daemon is absent it starts one for you.

The lockfile

.ripplo/ compiles to .ripplo/ripplo.lock. Commit it. The Ripplo server reads the lockfile on every push, so your dashboard and CI always reflect what's actually in the branch. npx ripplo compile --check in a pre-commit hook (installed by setup) keeps it fresh.

Worktrees

Ripplo is built for parallel feature work via git worktree. Each worktree gets its own dev session, scope, debug artifacts, and lockfile checkout, while auth and project config are shared globally, so a fresh worktree is ready to run as-is.

Two things to handle per worktree: copy your gitignored env file in (or point envFiles in .ripplo/project.json at a shared path outside the tree), and pick a distinct dev-server port, updating RIPPLO_APP_URL and RIPPLO_ENGINE_URL to match. ripplo doctor flags both if you forget.

Other commands

npx ripplo --help lists everything. Beyond setup you'll mostly use lint (compile + typecheck your .ripplo/), doctor (auth, env, and lockfile health), and scope (manage which flows the current session is responsible for).

License

© Ripplo LLC. All rights reserved. Use is subject to Ripplo's Terms of Service.