Local Review logo

Local Review

Open source · MIT · runs on your machine

Review your PR stacks before you create them.

A coding agent can write a dozen tidy commits in an afternoon. Reviewing them properly is the slow part, and GitHub is a poor place to start: once a PR is open, other people can see it, CI runs on it, and every round of fixes is a force-push.

Local Review shows every commit on your branch as its own pull request, grouped into the stacks you mean to open, in a GitHub-style review UI that runs on your laptop. Comment, get your agent to fix things, and mark PRs ready while it's still just you and your agent. Nothing goes to GitHub until the stack is right.

One review round trip: comment on a range of lines, the agent's reply lands in the thread live, resolve it, mark the PR ready, and the stack's tally ticks from 1/3 to 2/3. Recorded against Orchard, the fictional demo project that ships with the app.

One Commit, One PR

The review you'd do on GitHub, before GitHub

Every commit in the range gets a Conversation tab, a Files changed tab, a number and a readiness badge — the PR it's going to become. They're grouped into colour-coded stacks down the left, across one repo or several, so you review the shape of the thing you actually mean to send.

It reads like the page you already know, which is the point: there's nothing to learn. The one thing it deliberately doesn't do is look like github.com.

Local Review showing a PR: a deep plum header with a “not on GitHub” pill, a sidebar of colour-coded PR stacks with readiness badges, and the PR's title, Draft/Ready toggle and Conversation tab
PR #6 of a four-repo stack, mid-review. Everything here is the fictional Orchard demo project.

Quick Start

One command, no account

Local Review is an npm package. Needs Node.js 22 or later and git, on macOS or Linux. There's nothing to sign up for, no API key, and nothing phones home — it reads your repos and serves a UI on localhost.

Not ready to point it at your own work yet? Hit Add the example projects on the welcome page and you get Orchard — a made-up app reviewed across four repos, with stacked PRs, review threads and a fully merged stack to click around — in about a second, with no network. Remove examples hides them again and deletes nothing.

Quick Start
# create a project to review
npx local-review init my-feature

# serve the UI on localhost:5622
npx local-review

# ~/.local-review/projects/my-feature/project.yaml
repos:
  - path: ~/code/my-service
    branch: me/my-feature
    base: origin/main
    stacks:
      - title: Groundwork
      - title: The feature itself
        starts_at: "Add the feature flag"

Describe the Work

A project is one YAML file

Name the repos involved, the branch to review in each, and where each stack starts. The range runs from the branch head back to its merge-base with the base you give it, and stacks are picked by commit subject — so they survive every rebase, amend and reorder you do on the way through. Edits to the file are picked up live.

A project.yaml excerpt naming a repo, its branch and two stacks by the commit subject each starts at, beside the sidebar it produces: the same stacks, colour-coded, with their PRs and readiness badges
The file on the left makes the sidebar on the right. Fictional demo project.

Across Repositories

One change, four repos, one review

Real features rarely live in one repo. A change that touches the API, the client SDK, the web app and the infra is one piece of work — and a stacking tool that only understands a single repository makes you review it as four unrelated piles.

A Local Review project spans as many repos as you like, each with its own branch, base and stacks. Commits that don't belong to a stack yet sit in Unstacked, and work you want to keep out of this round goes in a follow-on stack — held back, faded, and left out of the totals.

The sidebar's sections for three repos — orchard-sdk, orchard-web and orchard-infra — each with its branch, its ready tally, and its own colour-coded stacks plus an Unstacked group

Works With Your Agent

Plain files in, plain files out

There's no plugin and no API key. Your review lives in YAML files under ~/.local-review, so any coding agent that can read and write files can take part — Claude Code, Codex, or whatever you're using next year. It reads your threads, fixes each commit where it stands, and writes its reply into the same file. The reply shows up in your browser as it works.

A thread on five lines of Go: the reviewer points out that a spot on offer still looks free, and Claude, marked as an agent, replies with two ways to fix it and asks which to do
The agent is just another commenter — badged, so you always know which is which
reviews/my-service/3f9c2e1….yaml
threads:
  - id: t-1a2b3c4d
    path: src/config/loader.ts
    line: 42
    resolved: false
    comments:
      - author: ada
        body: |
          This swallows the parse error. Can we
          surface the file name and line instead?
      - author: claude
        body: |
          Done in the amended commit: the error now
          reads "config.yaml:12: unexpected key".

A guide written for agents

local-review guide prints the agent guide: the data model, how to answer threads, how to fix a commit mid-stack, how to publish, and what to do after the merges.

A plan, not guesswork

local-review plan prints exactly what each PR should be on GitHub — branch, base, title, body — as Markdown, JSON or YAML, so publishing is mechanical.

One prompt to hand off

Paste the hand-off prompt into your agent and it works through your open threads the way the guide says: fix, reply, and resolve only what it should.

Files Changed

All the review furniture you expect

Split or unified diffs, a file tree, comments on a line or a range, resolvable threads, Viewed checkboxes, and keyboard shortcuts for stepping through commits and files. Readiness badges show where every PR in every stack stands, at a glance.

The Files changed tab: a file tree with Viewed checkboxes, a unified diff of a Go file, and an inline thread on a range of lines with the reviewer's comment and the agent's reply
7 files changed, 3 viewed, one thread already answered. Fictional demo project.

Stacks you can read at a glance

Each stack is a coloured box with a tally on it: 2/2 merged, 3/3 ready, 1/3 ready. Every PR carries a badge for one of four states — draft, ready, published, merged — and while it's a draft that badge is a pie that fills as you resolve threads and tick files off. The question "what's left?" is answered by looking, not by counting.

Three stacks in the sidebar: Groundwork marked 2/2 merged, Joining and leaving marked 3/3 ready, and Automatic promotion marked 1/3 ready, with a follow-on stack held back below
A review thread marked Outdated, showing where it originally sat in the file before the commit was amended, with the agent's reply explaining the fix

Following Rebases

Fixing a commit doesn't lose the review

Reviewing a stack means rewriting it. The agent amends commit three, rebases the five above it, and every SHA in the range changes. On GitHub that's a force-push and a pile of "outdated" comments nobody reads.

Local Review re-attaches each review to the commit it belongs to after the rewrite, and a thread whose lines have moved on is marked Outdated with the code it was written against still attached — so you can see what was said and check it got done.

Publishing

Then it goes up as a GitHub stack

GitHub's own stacked pull requests went generally available on 6 October 2026. Each PR's base is the branch below it, GitHub shows a stack map in the header, merges bottom-up and retargets the rest as each one lands. That's exactly the shape Local Review has been preparing.

Mark each PR ready. local-review plan prints every branch, base, title and body, and on your go-ahead your agent opens the stack with gh pr create, links it with gh stack link, and records each PR number back in the review. Local Review itself never talks to GitHub.

After they merge, the agent freezes them as landed PRs, so a finished stack keeps its numbers, its threads and its place in the picture instead of evaporating.

The Draft | Ready toggle set to Ready with 3 of 3 done, and below it the output of local-review plan for that PR: its commit, branch, base, status ready, title, and GitHub: not created

Ready, and the plan for what it becomes on GitHub. Fictional demo project.

The Stack Picture

The whole thing on one card

Every repo, every stack, every PR, with lines added and removed on a shared square-root scale so the bars mean the same thing everywhere. It's drawn on the server, so you can copy it to the clipboard or download it — which makes it a decent thing to paste into the chat where you're explaining what you're about to send.

A generated stack picture titled Class waitlists: 4 repos, 7 stacks, 18 PRs, with each repo's stacks drawn as coloured boxes and every PR's added and deleted lines shown as a bar

Guarantees

Safe to point at your work

You're going to aim this at the repo you get paid to work on. Three things it will not do, each written down as a documented guarantee rather than a good intention.

Read-only

It never fetches, checks out, commits or rebases. Every git call goes through one read-only allow-list, so it cannot modify the repos it is showing you.

Read the guarantee

Never deletes

Your review lives in ~/.local-review, never in your repos. Writes are atomic, nothing is unlinked, and it is snapshotted every hour something changes.

Read the guarantee

Localhost only

It binds 127.0.0.1 and rejects any non-localhost Host or Origin header. It never talks to GitHub — your agent does the git and GitHub work.

Read the guarantee

Where It Fits

In front of whatever you stack with

Every stacking tool starts from the same place: a series of commits on your machine. They differ in how they turn those commits into pull requests. Local Review works on the commit side, before any of them runs — so it needs nothing from yours.

Local commits
The stack your agent just wrote, on your branch
Local Review
Review · comment · agent replies · regroup · mark ready
Your stacking tool
gh stack · ghstack · Graphite · Sapling · spr · git-spice · jj
Stacked PRs on GitHub
With the titles and descriptions you approved
GitHub native + gh stack
What it publishes to by default
Graphite, git-spice, git-town
Chained bases on GitHub
ghstack, Sapling, spr
Synthetic or per-commit branches
jj, git-branchless, Gerrit
Local-first stack editing

Two habits make it work well with any of them: keep commit subjects stable and unique — they're what carries your review across a rebase and picks your stacks — and rebase with --update-refs so per-commit branches move with their commits.

Key Features

Every Commit Is a PR

Each commit gets a Conversation tab and a Files changed tab, numbered and grouped into colour-coded stacks: one PR per commit, the way the stack will go up on GitHub.

Stacks Across Repos

One project can span several repos, each with its own branch and stacks, so a change that touches the API, the client and the infra is reviewed as one piece of work.

Your Agent Replies In Place

Comments are plain YAML files. Your agent reads them, fixes the commits and replies in the same files, and its replies appear in your browser as it works.

reviews/orchard-api/3f9c2e1….yaml
threads:
  - resolved: false
    comments:
      - author: claude
Read-Only By Construction

It never fetches, checks out, commits or rebases. All git access goes through one read-only allow-list, so it cannot touch the repos it shows you.

Local, And Careful With Your Work

It never talks to GitHub and only answers on localhost. It never deletes your review, and snapshots it every hour that something changes.

Publish When It's Right

When a stack is ready, your agent opens it as GitHub stacked PRs with the titles and descriptions you approved, one stack at a time, then records what it created.

Threads Survive Rebases

Stacks are picked by commit subject and reviews re-attach to their commits after an amend or a rebase. A thread whose lines moved is marked Outdated, with its original code kept.

Stack Pictures

A server-drawn card of every repo, stack and PR with added and removed lines on one shared scale. Copy it to the clipboard or download it to show someone the shape of the work.

Example Projects In One Click

A first run offers a made-up four-repo project with stacked PRs, agent replies and a merged stack — seeded in about a second with no network, and removable without deleting anything.

Why I built it

The review moved, and the tools didn't

Almost all of my code is written by agents now. That changed where the hard part is: not typing the code, but reading it — a whole stack of commits at a time, most of which are fine, some of which are not, and all of which arrive at once.

GitHub is the wrong venue for that first pass. Opening the PR is the commitment: it's visible, CI starts burning, and every round of fixes is a force-push that scatters the conversation. What I wanted was the GitHub review page, pointed at commits that haven't gone anywhere yet, with the agent able to answer me in it.

So that's what this is. It's read-only on the repos, it has no idea GitHub exists, and the review is a directory of YAML files that both of us can edit. When the stack is right, the agent sends it.

From the Blog

Building Local Review in public

Why it exists, how it's built, and what reviewing an agent's work actually takes.

Local Review Before PR Review

Local Review Before PR Review

It is faster to generate lots of code than it is to read, understand, push back on or approve lots of code. The balance of effort is shifting hard toward the review side - so I built Local Review, a GitHub-style PR UI for the stack of commits still sitting on my laptop.

View all posts →

Try it on your next stack

npx local-review — MIT, no account, read-only on your repos.

Every screenshot and the video on this page were captured from Local Review's own demo test bed. The project they show — "Class waitlists", across four orchard repos — is fictional, as are its authors; it ships with the app as a one-click example so you can click around a realistic review without pointing anything at your own code.