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

shotlist

v0.5.0

Published

Repeatable, annotated UI screenshots from declarative recipes. No code per shot.

Readme

shotlist

Take annotated UI screenshots from YAML recipes, using Playwright.

shotlist opens your running site, drives it to the state you describe, clips a region, draws callouts on it, and writes the image where you want it. Each screenshot is a YAML file. There is no per-screenshot code.

shotlist.dev/docs is the reference — every key, every step verb, every query primitive. This file is the short version.

Install

This is a Node.js module available through the npm registry.

Before installing, download and install Node.js. Node.js 20 or higher is required.

If this is a brand new project, make sure to create a package.json first with the npm init command.

Installation is done using the npm install command:

npm install -D shotlist playwright

pnpm and yarn work the same way.

Playwright is an optional peer dependency — shotlist does not install it, because its postinstall downloads browsers. You need it whenever shotlist writes an image, which includes --check and a source: file recipe, since the callouts are drawn in a page. --init, --help and listing recipes need no browser and launch none.

Quick start

npx shotlist --init

writes a commented shotlist.config.yaml and a first recipe. Or set the two up by hand:

1. Configure the project onceshotlist.config.yaml in the project root:

site:
  url: http://localhost:3000
  viewport: { width: 1440, height: 900 }
  scale: 2
  theme: dark

install:
  guide: content/guide/images

2. Write a recipescreenshots/recipes/order-row.yaml:

name: order-row
install: guide

setup:
  - click: { role: button, name: Orders }

clip:
  css: '.order-row'
  contains: Acme Corp
  pad: 20

marks:
  amount: { within: clip, text: $42.00 }
  status: { within: clip, text: Open }

callouts:
  - { mark: amount, text: What they owe }
  - { mark: status, text: Where it stands }

3. Shoot it:

npx shotlist order-row --install

The image is written to screenshots/out/order-row.png, and --install copies it to content/guide/images/order-row.png. PNG is the default; image.format also takes jpeg and webp, per project or per recipe.

Documentation

| Page | What it covers | | ------------------------------------------------------------------------------------------------ | --------------------------------------------- | | Your first screenshot | A lesson: install, a recipe, a callout | | Add shotlist to a project | Setting up in an app you already have | | Configuration file | Every key, starting the site, style and fonts | | Recipe file | Every field, and annotating an existing image | | Steps | The step vocabulary | | Queries | Sources, filters, traversal, frames, finders | | Callouts and masks | Labels, numbered discs, masking | | Macros and data files | Sharing setup, driving a shot from a list | | Command line | Every flag, the API, editor and agent support | | Keeping a screenshot current | --check, diffs, and a shot that changes | | Undo what a shot changed | teardown, for a recipe that writes | | What a configuration can do | What a run is allowed to reach |

Commands

npx shotlist --init               # write a starter config and recipe
npx shotlist                      # list every recipe
npx shotlist <name> [<name>…]     # shoot into paths.out
npx shotlist <name> --install     # …and copy to its install destination
npx shotlist --all --install      # shoot everything
npx shotlist --all --keep-going   # …carrying on past a recipe that fails
npx shotlist --check              # compare against committed images
npx shotlist --check --diff       # …and write a before/after/changed image
npx shotlist --check --json       # …and report it as JSON on stdout
npx shotlist --lint               # check every YAML; no browser, no site needed
npx shotlist --login admin        # sign in by hand, and save the session
npx shotlist --help               # the full list, from the tool

A recipe is data

A recipe is data. There is no step that evaluates JavaScript and there will not be one: if a screenshot cannot be described, that is a missing verb or query primitive, and it gets added. See CONTRIBUTING.md.

Running a config you did not write

shotlist also runs in automation, where the config may come from a fork's pull request or from whoever submitted it. A shot list only ever opens its own site, and never reads or writes .env, .git, .ssh and their like — in every mode, with no flag to set. For the rest, --untrusted starts no processes, opens nothing on the runner's own network, and stays inside the project.

Full detail, and what it does not cover, at shotlist.dev/docs/explanation/security-model.

Contributing

Any constructive contribution is welcome! You may contribute in any way you feel comfortable, from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, fixing a typo, and more!

Everything you need is in CONTRIBUTING.md: setup, the commands, the code style, and what "done" means.

License

MIT © Nicola Mustone — see LICENSE.