PatchStory

Generate a static, interactive PR walkthrough from a GitHub pull request,
git branch comparison, commit range, or raw diff — as a self-contained folder of
HTML/CSS/JS you can zip, email, attach to a ticket, or open locally in a browser
with no server.
Instead of dumping a flat file list, PatchStory tells the change as a story:
logical chapters, each with intent, the relevant diff hunks, reviewer questions,
risk level, and verification steps.
patchstory diff main...my-branch --out ./walkthrough
patchstory diff main...my-branch --zip
patchstory commits abc123..def456
patchstory file ./my-pr.diff
patchstory github https://github.com/org/repo/pull/123 -g anthropic
patchstory render ./pr-walkthrough.json --out ./site
- Local-first. No hosted service, no database, no auth.
- Zero runtime dependencies. Custom diff parser, custom ZIP writer, built-in
fetch for the optional AI adapter. Build-time deps only: esbuild,
typescript, and highlight.js (bundled into app.js, so the CLI itself
ships no node_modules).
- Portable output. Opens over
file:// (data embedded in data.js, no
fetch required). Zip-friendly.
- AI optional. A heuristic generator always works with no API key. AI
improves the story; it is never required.
What it looks like
A 6-file PR — "Add Redis-backed rate limiting to the public API" — walked
through by PatchStory. The source diff and the agent-authored story are tracked
in examples/rate-limiting.diff and
examples/rate-limiting.json; render the page
below yourself with:
patchstory render examples/rate-limiting.json --diff examples/rate-limiting.diff --single-file --open
The overview maps the whole change: a "start here" reading list, the stats,
the recurring themes, and a risk-rated reviewer path.
Open a chapter and you get its intent, the reviewer questions to ask, the
verification steps, and the syntax-highlighted diff (unified or split,
collapsible, with per-file "mark reviewed" state).
Quick start
git clone https://github.com/russ/patchstory.git
cd patchstory
npm install # installs deps and builds (via the `prepare` script)
# try it on the bundled example (no git repo needed)
node packages/cli/dist/patchstory.mjs file ./examples/sample.diff --single-file --open
npm install runs the build automatically. To rebuild after changes, run
npm run build. You can npm link the patchstory package (or run
node packages/cli/dist/patchstory.mjs) to get the patchstory command on PATH.
Requirements: the built CLI runs on Node ≥ 20. Local development (the
npm test runner, which executes TypeScript directly) needs Node ≥ 22.6.
Architecture
The guiding principle: the AI-generated story is separate from the renderer.
The renderer consumes a JSON document + a parsed diff and does not care whether
the story came from a heuristic, OpenAI, Claude, a local model, or a human.
┌─────────────┐ raw diff ┌──────────────┐ WalkthroughDocument ┌──────────────┐
│ sources │ ───────────▶ │ generator │ ────────────────────▶ │ renderer │
│ git / gh / │ │ none | │ + ParsedDiff │ static site │
│ file / PR │ │ anthropic │ │ (vanilla TS) │
└─────────────┘ └──────────────┘ └──────────────┘
\__________________________ pr-walkthrough.json ___________________________/
(canonical intermediate representation)
Packages (npm workspaces)