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

@ashartariq/flowdiff

v0.1.1

Published

PR UX diff tool for Cypress journeys — CLI

Readme

@ashartariq/flowdiff

PR UX diff tool for Cypress journeys. Captures named keyframe screenshots on every PR, diffs them pixel-by-pixel against a baseline, and posts a rich HTML report as a GitHub Actions artifact with an inline PR comment.

Works with any existing Cypress test suite — no test rewrites needed, just add cy.flowSnap() calls at the UI moments you care about.

How it works

main push → capture baseline screenshots → upload artifact
PR open   → capture candidate screenshots → diff vs baseline → HTML report → PR comment
  1. Baseline run (on push to main): Cypress runs, cy.flowSnap() captures keyframes, flowdiff collect saves them as the flowdiff-baseline artifact.
  2. PR run (on pull request to main): Same Cypress run captures the candidate. flowdiff compare diffs every step pixel-by-pixel and generates a self-contained index.html report.
  3. PR comment: Shows changed/unchanged counts and links to the downloadable HTML report.

Install

npm install --save-dev @ashartariq/flowdiff
# or
pnpm add -D @ashartariq/flowdiff

Also install the Cypress plugin:

npm install --save-dev cypress-flowdiff

Cypress setup

See cypress-flowdiff for the full plugin setup. Quick start:

cypress.config.ts

import { installFlowDiffPlugin } from 'cypress-flowdiff';
export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      installFlowDiffPlugin(on, config);
      return config;
    },
  },
});

cypress/support/e2e.ts

import { addFlowSnapCommand } from 'cypress-flowdiff';
addFlowSnapCommand();

In your tests

cy.visit('/login');
cy.flowSnap('login page');
cy.get('[data-cy=submit]').click();
cy.flowSnap('after submit');

CLI

flowdiff collect   --cwd <dir>  [--screenshots <dir>]  [--run-id <id>]
flowdiff compare   --cwd <dir>  [--baseline <dir>]  [--candidate <dir>]  [--output <dir>]  [--threshold <n>]  [--artifact-url <url>]
flowdiff github-comment  --repo <owner/repo>  --pr <number>  --report <path>  [--artifact-url <url>]

collect

Scans cypress/screenshots/flowsnap/ and copies files into .flowdiff/candidate/ with a manifest.json.

node_modules/.bin/flowdiff collect --cwd .

compare

Diffs candidate against baseline, writes diff images and a self-contained index.html report to .flowdiff/report/.

node_modules/.bin/flowdiff compare \
  --cwd . \
  --baseline .flowdiff/baseline \
  --candidate .flowdiff/candidate \
  --output .flowdiff/report

Exit codes: 0 = no diffs, 1 = error, 2 = diffs detected (use for CI gating).

github-comment

Upserts a PR comment via the GitHub API. Usually called automatically by the composite action.

node_modules/.bin/flowdiff github-comment \
  --repo owner/repo \
  --pr 42 \
  --report .flowdiff/report/report.json \
  --artifact-url https://github.com/.../artifacts/...

Configuration

Create a flowdiff.config.ts (or .js, .json, or a "flowdiff" key in package.json):

import type { FlowDiffConfig } from '@ashartariq/flowdiff';

const config: FlowDiffConfig = {
  screenshotsDir: 'cypress/screenshots',   // where Cypress saves screenshots
  outputDir: '.flowdiff',                   // working directory for collect/compare output
  diffThreshold: 0.1,                       // per-channel diff sensitivity (0–1)
  pixelChangeFailThreshold: 0.02,           // % of changed pixels that counts as "changed" (0–1)
  maxKeyframesPerJourney: 20,               // cap on steps per journey
  maskRegions: [],                          // pixel regions to ignore during diff
};

export default config;

GitHub Actions

Add two workflow files to your repository:

.github/workflows/flowdiff-baseline.yml

Runs on push to main. Captures the baseline.

name: FlowDiff Baseline

on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: flowdiff-baseline
  cancel-in-progress: false

jobs:
  baseline:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Start app
        run: npx serve public -p 4000 &

      - name: Run Cypress
        uses: cypress-io/github-action@v6
        with:
          install: false
        env:
          CYPRESS_BASE_URL: 'http://localhost:4000'

      - name: Collect screenshots
        run: npx flowdiff collect --cwd .

      - name: Upload baseline
        uses: actions/upload-artifact@v4
        with:
          name: flowdiff-baseline
          path: .flowdiff/candidate/
          retention-days: 90
          overwrite: true

.github/workflows/flowdiff-pr.yml

Runs on PRs targeting main. Compares and comments.

name: FlowDiff PR

on:
  pull_request:
    branches: [main]

jobs:
  flowdiff:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      actions: read
      contents: read
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Start app
        run: npx serve public -p 4000 &

      - name: Run Cypress
        uses: cypress-io/github-action@v6
        with:
          install: false
        env:
          CYPRESS_BASE_URL: 'http://localhost:4000'
        continue-on-error: true

      - name: Collect candidate screenshots
        run: npx flowdiff collect --cwd .

      - name: Download baseline
        uses: actions/download-artifact@v4
        with:
          name: flowdiff-baseline
          path: .flowdiff/baseline/
        continue-on-error: true

      - name: Compare
        run: |
          npx flowdiff compare \
            --cwd . \
            --baseline .flowdiff/baseline \
            --candidate .flowdiff/candidate \
            --output .flowdiff/report
        continue-on-error: true

      - name: Post PR comment
        run: |
          npx flowdiff github-comment \
            --repo ${{ github.repository }} \
            --pr ${{ github.event.pull_request.number }} \
            --report .flowdiff/report/report.json
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        continue-on-error: true

      - name: Upload report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: flowdiff-report-pr-${{ github.event.pull_request.number }}
          path: .flowdiff/report/
          retention-days: 30

Report UI features

The generated index.html is fully self-contained (no CDN). Open it locally or download it from the Actions artifact.

  • Journey tabs — switch between different spec files
  • Step card grid — thumbnail previews with status badges and pixel-change %
  • Hover to diff — hover a card to reveal the diff overlay image
  • Click for detail — opens a 3-column panel (Baseline | Diff | Candidate)
  • Category toggles — 11 detection categories (colors, layout, typography, etc.) with sensitivity thresholds that update the "changed" count live
  • Baseline section — collapsible strip showing all baseline screenshots

License

MIT