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

@juangadm/pre-post

v0.2.0

Published

Visual diff tool for PRs — captures before/after screenshots of web pages

Downloads

316

Readme

pre-post

Visual diff tool that captures pre/post screenshots for PRs. Use it as a Claude Code skill for automatic visual documentation, or run it directly from the CLI.

Originally forked from before-and-after by James Clements / Vercel Labs.

What Changed from the Original

| Area | before-and-after | pre-post | |------|-----------------|----------| | Browser engine | agent-browser (Vercel-proprietary) | Playwright (direct dependency) | | Screenshot quality | 1x | 2x retina (deviceScaleFactor: 2) | | Route detection | Manual | Automatic from git diff (Next.js App/Pages Router, Remix, SvelteKit) | | Responsive capture | Single viewport | Desktop + mobile per route (--responsive) | | CLI subcommands | URL pairs only | detect, compare, run subcommands | | Skill orchestration | Basic capture | Full workflow: route detection, Claude refinement, user approval, PR posting | | Font/animation handling | None | Waits for document.fonts.ready, disables CSS animations |

How It Works

flowchart TD
    A[pre-post] --> B{Mode?}

    B -->|Manual| C["pre-post url1 url2"]
    B -->|Automatic| D["pre-post run"]
    B -->|Claude Code Skill| E["/pre-post"]

    D --> F["git diff --name-only"]
    F --> G{Detect framework}
    G -->|Next.js App Router| H[Map files → routes]
    G -->|Next.js Pages Router| H
    G -->|Remix / SvelteKit| H
    G -->|Unknown| I["Default to /"]
    H --> J[Route list with confidence]

    E --> F
    E --> K[Claude refines routes]
    K --> J

    C --> L[Playwright]
    J --> L

    L --> M{System Chrome?}
    M -->|Found| N[Use system Chrome]
    M -->|Not found| O[Use bundled Chromium]
    N --> P[Capture screenshots]
    O --> P

    P --> Q[Disable animations]
    Q --> R[Wait for fonts]
    R --> S[Take 2x retina screenshot]

    S --> T{Output}
    T -->|Default| U["Save to ~/Downloads"]
    T -->|--markdown| V{Upload}
    V -->|Default| W["Commit to .pre-post/ (blob+SHA URL)"]
    V -->|--upload-url| Y["Custom storage"]
    W --> Z[Markdown table for PR]
    Y --> Z

    style A fill:#4f46e5,color:#fff
    style L fill:#2563eb,color:#fff
    style S fill:#059669,color:#fff

Prerequisites

  • Node.js 18+
  • Chromium — install once via Playwright:
npx playwright install chromium

CI / Sandboxed Environments

pre-post needs a Chromium binary. In restricted environments where npx playwright install chromium fails (CDN blocked):

# Point to a pre-installed Chrome/Chromium binary
export PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/path/to/chrome

# This is treated as an explicit override — pre-post will fail with a
# clear error if the path is wrong, rather than silently falling back.

When no custom path is set, pre-post auto-detects in order: system Chrome, bundled Playwright Chromium, then any builds in ~/.cache/ms-playwright/.

If no browser is available at all, use image-only mode:

pre-post before.png after.png --markdown

Proxy URLs: If your git remote uses a proxy (e.g., http://proxy@host/git/owner/repo), set the repo explicitly:

export GH_REPO=owner/repo

Google Fonts: Container egress proxies typically block fonts.googleapis.com. Screenshots will render with system font fallbacks. This is cosmetic only — document.fonts.ready still resolves and layout is preserved.

Install

npm install -D @juangadm/pre-post

Basic Use

As a Claude Code Skill (recommended)

After making visual UI changes, say /pre-post or "take pre and post screenshots". Claude will:

  1. Detect affected routes from your git diff
  2. Propose routes for your approval
  3. Capture desktop + mobile screenshots (production vs localhost)
  4. Show you the screenshots for approval
  5. Upload and append markdown to your PR

From the CLI

Capture any two URLs:

pre-post site.com localhost:3000

Use existing images:

pre-post before.png after.png

CLI Subcommands

detect -- Route Detection

Detect affected routes from git changes:

pre-post detect                        # Auto-detect framework
pre-post detect --framework nextjs-app  # Force framework

Outputs JSON with route paths, confidence levels, and source files.

compare -- URL Comparison

Compare pre/post states across routes:

pre-post compare --before-base https://prod.com --after-base http://localhost:3000
pre-post compare --before-base URL --after-base URL --routes /dashboard,/settings
pre-post compare --before-base URL --after-base URL --responsive  # Desktop + mobile

run -- Full Auto

Combines detect + compare:

pre-post run --before-base https://prod.com --after-base http://localhost:3000

Options

Capture a specific element using a CSS selector:

pre-post url1 url2 ".hero"

Use different selectors for pre and post:

pre-post url1 url2 ".old" ".new"

Capture at mobile (375x812), tablet (768x1024), or custom viewport:

pre-post url1 url2 --mobile
pre-post url1 url2 --size 1920x1080

Capture the entire scrollable page:

pre-post url1 url2 --full

Output a markdown table for PR descriptions:

pre-post url1 url2 --markdown

Save to a custom location:

pre-post url1 url2 --output ./screenshots

Upload to a custom image storage service:

pre-post url1 url2 --markdown --upload-url https://my-s3-bucket.amazonaws.com

By default, --markdown commits screenshots to the PR branch (under .pre-post/) and serves them via GitHub blob URLs pinned to the commit SHA. This works for both public and private repos. Use --upload-url to point at your own storage instead. It auto-detects the protocol for 0x0.st, Vercel Blob, and any generic PUT endpoint (like S3). Screenshots auto-append to the PR body, newest on top.

Route Detection

Pre-post automatically maps git diff --name-only to affected UI routes:

| Changed File | Detected Route | Confidence | |---|---|---| | app/page.tsx | / | high | | app/dashboard/page.tsx | /dashboard | high | | app/(marketing)/about/page.tsx | /about (strips route groups) | high | | app/blog/[slug]/page.tsx | /blog/[slug] | high | | app/dashboard/layout.tsx | /dashboard | medium | | app/dashboard/components/Chart.tsx | /dashboard | medium | | globals.css, tailwind.config.ts | / | low | | app/api/*, middleware.ts | Skipped (no visual) | -- |

Supports:

  • Next.js App Router (route groups, dynamic segments, parallel routes, catch-all)
  • Next.js Pages Router (pages/, _app.tsx, _document.tsx)
  • Remix (routes/ directory)
  • SvelteKit (src/routes/+page.svelte)
  • Generic fallback (defaults to /)

Add Skill

Install as a Claude Code skill:

npx skills add juangadm/pre-post

The skill uses gh to detect the associated PR and Playwright for screenshots.

Credits

License

MIT