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

flowshot

v0.7.4

Published

Flow-based visual regression dashboard for Playwright. One command, one HTML file — screenshots connected as user flows with diff slider.

Readme

flowshot

npm version CI License: MIT

Flow-based visual regression dashboard for Playwright. One command, one HTML file — screenshots connected as user flows with diff slider.

Dashboard Dark

Why

Existing visual regression tools show screenshots as flat galleries. Flowshot shows them as user flows — screens connected with arrows, so you see the journey, not just the pages.

  • No server, no account — generates a single HTML file (~63 KB, fully self-contained)
  • Works with your existing Playwright snapshots — auto-detects the file naming from playwright.config.*
  • Diff mode with drag slider + fullscreen Compare / Expected / Actual / Diff tabs
  • Dark/light theme, sidebar navigation, lightbox zoom
  • Version badge in the report header — know which flowshot generated any report at a glance

Quick Start

# 1. Install
npm i -D flowshot

# 2. Create config
npx flowshot init

# 3. Edit flowshot.config.json — define your flows

# 4. Run Playwright visual tests
npx playwright test e2e/visual.spec.ts

# 5. Generate report
npx flowshot

How Diff Detection Works

Flowshot integrates with Playwright's built-in visual comparison. Here's the full workflow:

1. Create baseline screenshots

Run your visual tests to capture baseline screenshots:

npx playwright test e2e/visual.spec.ts --update-snapshots

This saves baseline PNGs to your snapshotDir (e.g. e2e/visual.spec.ts-snapshots/).

2. Make changes to your app

Edit components, styles, layouts — anything visual.

3. Run visual tests again

npx playwright test e2e/visual.spec.ts || true

When Playwright detects a difference, it generates three files in test-results/:

  • *-expected.png — the baseline
  • *-actual.png — what the screen looks like now
  • *-diff.png — pixel diff highlighted in red

4. Generate the flow report

npx flowshot

Flowshot scans test-results/ for those diff files, copies them to .flowshot/diffs/, and generates an HTML report.

5. Review diffs in the dashboard

Open the report and click Diff in the top bar:

  • CHANGED (red badge) — screens that differ from baseline
  • OK (green badge) — screens that match
  • Drag slider on each card to compare expected vs actual side-by-side
  • Fullscreen button (top-right of each card) — opens fullscreen slider compare
  • Sidebar shows warning icons on flows with changes
  • Summary bar shows total changed vs unchanged count

6. Accept or fix

# If the changes are intentional — update baselines:
npx playwright test e2e/visual.spec.ts --update-snapshots

# If something broke — fix your code and re-run:
npx playwright test e2e/visual.spec.ts

One-command shortcut

Combine test + report in one step:

npx playwright test e2e/visual.spec.ts || true && npx flowshot

Or add to your Makefile:

test-visual-review: ## Visual test + open flow dashboard
	npx playwright test e2e/visual.spec.ts --project=chromium || true
	npx flowshot

Recommended Playwright threshold

Playwright's default maxDiffPixelRatio is 0 (exact match). Common settings:

const screenshotOpts = {
  maxDiffPixelRatio: 0.05,  // allow 5% pixel diff
  threshold: 0.2,           // Playwright default color threshold
}

Setting maxDiffPixelRatio too high (e.g. 0.35) will cause real changes to go undetected.

Screenshots

Flow View — Dark Theme

Dashboard Dark

Flow View — Light Theme

Dashboard Light

Single Flow Detail

Flow Detail

Diff Mode

Diff Mode

Config

flowshot.config.json:

{
  "snapshotDir": "e2e/visual.spec.ts-snapshots",
  "testResultsDir": "test-results",
  "platform": "chromium-darwin",
  "views": ["mobile", "desktop"],
  "outDir": ".flowshot",
  "flows": [
    {
      "name": "Auth Flow",
      "steps": [
        { "screen": "auth", "label": "Login", "path": "/auth" },
        { "screen": "home", "label": "Home", "path": "/" }
      ]
    }
  ],
  "components": [
    { "screen": "header-component", "label": "Header" }
  ]
}

| Field | Description | |-------|-------------| | snapshotDir | Where Playwright stores baseline screenshots | | testResultsDir | Where Playwright writes test results (diffs on failure) | | platform | Snapshot filename suffix, e.g. chromium-darwin | | views | Viewport names matching your snapshot filenames | | outDir | Output directory for report and collected diffs | | flows | Array of user flows, each with ordered steps | | components | Shared UI components (header, footer, etc.) | | filePattern | Snapshot filename pattern (optional). Auto-detected from snapshotDir if omitted. Default: {screen}-{view}-{platform} |

Snapshot naming convention

By default, flowshot expects Playwright snapshots named as:

{screen}-{view}-{platform}.png

For example: home-mobile-chromium-darwin.png, auth-desktop-chromium-darwin.png

This matches Playwright's default {name}-{projectName}-{platform}.png when your project name equals the view name (mobile, desktop).

Auto-detection

If you omit filePattern, flowshot resolves it in this priority order:

  1. playwright.config.{ts,js,mjs,cjs} — parses snapshotPathTemplate (or uses Playwright's default template if unset), extracts projects[].name to auto-populate views, and sets platform = process.platform when the template injects {-snapshotSuffix}
  2. Disk scan — tries these candidate patterns against files in snapshotDir until one matches:
    1. {screen}-{view}-{platform} (Playwright default on modern versions)
    2. {screen}-{project}-{platform}
    3. {screen}-{view}
    4. {screen}-{project}
    5. {screen}
  3. Fallback to {screen}-{view}-{platform}

Detected source + pattern is logged on report generation, e.g.:

🔍 Detected [playwright.config] pattern: {screen}-{project}-{platform} (playwright.config.ts projects=[chromium,mobile] platform=darwin)

Set filePattern explicitly to skip detection entirely.

Cross-OS CI note

When Playwright uses its default template, baselines get an OS suffix (-darwin on Mac, -linux on Linux CI). Flowshot auto-sets platform = process.platform at runtime, so the same config works on both — each OS resolves its own baselines. This matches Playwright's per-OS baseline best practice (font rendering differs across platforms).

Custom file patterns

If auto-detect doesn't fit your setup, override filePattern in flowshot.config.json. Available tokens:

| Token | Value | |-------|-------| | {screen} | Screen name from flows[].steps[].screen | | {view} | Viewport name from views | | {project} | Alias for {view} (use whichever reads better) | | {platform} | Value of platform config field |

Examples:

// Default — Playwright with project per viewport
"filePattern": "{screen}-{view}-{platform}"
// → home-mobile-chromium-darwin.png

// Project name only, no platform suffix
"filePattern": "{screen}-{project}"
// → home-mobile.png

// Screen + view, no platform
"filePattern": "{screen}-{view}"
// → home-mobile.png

Auto-Detect Flows

Flowshot can automatically discover your app's screens and generate flows — two ways:

flowshot detect — from test files + snapshots (no running app needed)

Scans your Playwright snapshot directory and test files to find screens and build flows:

flowshot detect              # preview detected flows
flowshot detect --write      # create flowshot.config.json from detected
flowshot detect --merge      # add new flows to existing config

How it works:

  1. Scans e2e/visual.spec.ts-snapshots/ for screenshot files
  2. Parses e2e/*.spec.ts for page.goto() and toHaveScreenshot() patterns
  3. Groups screens by section (heal-your-heart, know-your-self, etc.)
  4. Detects component screenshots (header, footer)

flowshot crawl — by actually browsing your app with Playwright

Opens your app in a real browser, finds links, clicks them, takes screenshots:

# Start your app first, then:
flowshot crawl --url http://localhost:3000

# Options:
flowshot crawl --url http://localhost:3000 --mobile                  # mobile viewport
flowshot crawl --url http://localhost:3000 --max-pages 20            # limit pages
flowshot crawl --url http://localhost:3000 --max-depth 2             # limit link depth
flowshot crawl --url http://localhost:3000 --ignore "/admin,/api"    # skip paths
flowshot crawl --url http://localhost:3000 --write                   # save to config

How it works:

  1. Reads existing flowshot.config.json for snapshotDir and platform (if present)
  2. Opens the URL in Playwright Chromium
  3. Finds all <a href> links on the page
  4. Visits each link, takes a screenshot
  5. Follows links from discovered pages (up to max-depth)
  6. Groups pages by URL section into flows
  7. Screenshots saved to snapshotDir with naming {screen}-{view}-{platform}.png
    • If no config exists, falls back to .flowshot/crawl-snapshots/

When using --write or --merge, existing config fields (snapshotDir, platform, views, components) are preserved — only flows are updated.

Requires playwright as a peer dependency: npm i -D playwright

flowshot init — smart init

When you run flowshot init, it automatically tries detect first. If snapshots exist, it generates config from them. Otherwise, creates an example config.

Commands

flowshot              # collect diffs + generate report + open browser
flowshot init         # auto-detect flows or create example config
flowshot detect       # detect flows from snapshots + test files
flowshot crawl        # discover pages by crawling your app
flowshot crawl --ignore "/content,/admin"  # skip specific paths
flowshot collect      # collect diff images from test-results/
flowshot report       # generate HTML report
flowshot report --open      # generate and open in browser
flowshot report --inline    # embed images as base64 (portable for CI)
flowshot report --collect   # collect diffs before generating

CI Usage

Generate a portable report with embedded images:

npx flowshot report --collect --inline

Upload .flowshot/report.html as a CI artifact.

GitHub Actions example

- name: Visual regression
  run: npx playwright test e2e/visual.spec.ts || true

- name: Generate flow report
  run: npx flowshot report --collect --inline

- uses: actions/upload-artifact@v4
  with:
    name: flowshot-report
    path: .flowshot/report.html

Stack

| Layer | Choice | Notes | |---|---|---| | Runtime dep | Commander | Only non-Node runtime dep. playwright is an optional peer dep used by the crawl command | | Report UI | Svelte 5 (runes) | Compiled — no Svelte runtime shipped to users | | UI build | Vite 8 + vite-plugin-singlefile | Bundles the Svelte app into one self-contained HTML (~63 KB / 22 KB gzip) | | Library build | tsup (esbuild) | src/cli.ts + src/index.ts → CJS + ESM + .d.ts | | Types | TypeScript 5.7 strict | Bundler resolution, resolveJsonModule | | Tests | node --test + node:assert | Built-in runner, zero test deps, ~50 ms for 11 tests | | CI | GitHub Actions | ci.yml runs typecheck + build + tests on push/PR; release.yml also gates publish on tests | | Task runner | Makefile | Short aliases over npm scripts |

Published package: 51.5 KB tarball, 190 KB unpacked, 1 runtime dep

Report output: single self-contained HTML file — no external requests, drop it anywhere

Development

git clone https://github.com/thingnoy/flowshot
cd flowshot
npm install

Common tasks (via make or npm):

| Command | What it does | |---|---| | make build | Full build: tsup for CLI/lib + vite for the Svelte report template | | make dev-ui | Vite dev server with HMR on the report template (mock data auto-loaded) | | make test | Build + run integration tests (node --test) | | make typecheck | tsc --noEmit | | make publish-check | Build + test + npm pack --dry-run preview |

Architecture

  • src/cli.ts — Commander-based CLI entry
  • src/report.ts — image map builder + template renderer
  • src/detect-*.ts — snapshot pattern detection (filePattern / playwright.config / disk scan)
  • src/report-ui/ — Svelte 5 app for the report UI, compiled by Vite to a single self-contained HTML file (dist/report-template.html). At runtime generateReport() reads this template and substitutes a /*FLOWSHOT_DATA*/ marker with the JSON payload

Testing

Integration tests use Node's built-in test runner (no vitest/jest — zero test deps):

make test
# or
node --test test/*.test.mjs

Coverage:

  • Pattern detection — explicit filePattern, playwright.config.* parsing, disk-scan fallback, defaults
  • Report resolver — component naming across 4 styles (project-based, legacy {screen}-{platform}, bare {screen}, missing file), single-file HTML output, filePattern round-trip

CI runs tests on every push + PR to main; releases block on a failing build or test run.

License

MIT