Local Review Before PR Review

As it gets ever faster, cheaper and easier to generate large amounts of source code, the bottleneck continues to shift toward the review side of things. It's faster to generate lots of code than it is to read, understand, push back on, or approve lots of code, and the balance of effort between those two sides is tipping hard toward reviewing.

There's as much value for the author of a PR in splitting it up and making it comprehensible as there is for the reviewer. The value of what software engineers do was never the code they output, but the systems that emerge as a result. Working on comprehensible pull requests helps the author make sure they fully understand what they're submitting, as much as it helps the reviewer grok what the hundreds or thousands of lines they're being asked to review are all about.

A rendered stack picture: one repo on a branch, four colour-coded stacks containing ten pull requests, each PR with its branch name and a green and red bar showing lines added and deleted on a shared scale.
One feature, cut into four stacks of small PRs, every size on the same scale. Local Review draws this and puts it on your clipboard. The project is Orchard, the fictional demo that ships with the app.

What code review is actually for

One function is obviously to find bugs, and agents are increasingly good at that, for the same reason they're increasingly good at writing better and better software in the first place.

Another key function of pull requests is to clearly communicate a proposed change to other people who have the knowledge and experience to judge whether that change is good, and whether it's compatible with whatever larger goals the team has. That makes it critically important that our pull requests are very easy to understand, because every reviewer is currently drowning in review requests.

Pull requests also exist to update the mental model of the humans involved, and to align the change with perhaps intangible or longer-term goals the code-writing agent is not even aware of. In most companies there is far more tribal knowledge distributed in the brains of employees than any AI system has access to, and that will likely continue to be true. Part of why we have pull requests is to make sure changes adhere to our culture, or our taste as it were, as well as to simple correctness, and to let other people weigh in.

AI solves some of that and not the rest. What it can't do is the judgment calls needing context the agent doesn't have: subtleties, quirks, odd bits of one-time behaviour that may not be written down anywhere. Agents reveal things the humans never would have all the time too - but there's still a human factor in really grokking what a PR is about, and that's becoming a greater and greater portion of the time engineers spend.

PRs are getting bigger

DX has telemetry from over 400 organizations: median PR size grew from 44 lines to 72 lines between July 2025 and June 2026, while the share of code those developers said was AI-authored went from 27.4% to 51.9% in a single quarter. Faros AI, with two years of data from 22,000 developers, captured data that show median time in review up 441.5%, and PRs merged with no review at all up 31.3%.

SmartBear's study of a Cisco programming team found that developers should review no more than 200 to 400 lines of code at a time, and that beyond 400 the ability to find defects diminishes. So PRs are getting bigger, review is taking far longer, more is going through unreviewed - and we've known for twenty years that big reviews find proportionally fewer bugs. With all the obvious caveats about how a line is not a line, that's a fairly clear picture.

Smaller PRs are better than bigger PRs

The larger the number of lines changed, the more effort is involved in reviewing your PR. That should sound pretty obvious, and the corollary is true as well. There's only so much cognitive load that can come from a 200-line PR; a 1,000-line PR is sometimes not so bad, but most of the time it's obviously far more difficult.

GitHub launched stacked pull requests recently, and that's an incredibly useful tool. It lets you craft a stack of carefully constructed PRs, each of which is small and iterative by itself, doesn't boil the ocean, and can easily be consumed by a reviewer.

Model PRs and stacks of PRs locally

Normally, when I'm working on something large and complex (especially if it takes hours or days, and agents have been helping write the code), at a certain point I lose the ability to keep all of that diff in my head. I need to start seeing it on the screen. I'm not ready for a pull request yet, but a draft pull request turns out to be a pretty convenient place to get that diff, and I've sometimes made one in the past for exactly that reason.

Two problems:

  1. Overzealous colleagues could, and sometimes do, find these draft PRs and start commenting on them, even if I'm nowhere near ready for them to be looked at.
  2. If I want my agents to change some stuff based on me looking around, I want to click, leave comments like I normally would in a review, and have the agent act on them. Pushing to GitHub, making a draft PR, making a bunch of comments to myself and then answering them myself looks a little bit nuts.

So I wanted to bring that locally. I built Local Review to help me do that. Local Review is a simple tool that helps you organize, visualize, rearrange, and orchestrate large or complex sets of code changes across multiple PRs, stacks of PRs, and even repositories.

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.
A PR in Local Review, mid-review.

Commits as a proxy for pull requests

The core of it is pre-assembling one or more stacks of pull requests across one or more GitHub repos. For each repo the project config names a branch, and each commit along it is a proxy for a pull request on GitHub when you're finished.

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.

So the UI renders what looks like a bunch of stacked PRs while keeping the easy manipulability of one commit per PR. Only when we create the real pull requests do we decide whether to split any into multiple commits - and usually we don't need to, because the objective all along was that they stay small.

What that looked like at work

The first time I used this at work I thought I was going to have a stack of 4 PRs. It turned into about 14 - which became 12 across 3 linked stacks of 4, plus 2 follow-ons. It was only because I was using Local Review that it became clear there were in fact 3 clear sub-stacks within that 14, or at least it was a lot easier to see. And there were coordinated changes that had to go out across 2 additional repos. For that project - about 20 pull requests across 3 repos - having the entire overview on a single page was incredibly useful.

A stack picture for a whole project: four repos, each with its branch, its colour-coded stacks and a size bar for every pull request, with a summary line reading 4 repos, 7 stacks, 18 PRs.
The same picture, scoped to a whole multi-repo project instead of one repo.

How I actually work with it

Local Review is read-only on your repositories - it never fetches, checks out, commits or rebases, and the only thing it writes is your review, into ~/.local-review. It needs pairing with something that does the actual work.

I use Paddock all day every day, with Claude Code underneath it. Mostly I'm just telling Claude what I want - break this one up, bring these together, go and look through that. Recently it recommended swapping the order of some of the sub-stacks, which turned out to make all the sense in the world: the diffs got more straightforward, and it revealed that one of the later stacks could be detached entirely into a later project.

Then I go through the PRs and the stacks one by one in something that feels like a GitHub-style review tool. The comments are entirely separate from GitHub's: they stay local and get written to a YAML file, which my agent can read and act on.

One round trip: comment, the agent answers in the thread, resolve it, mark the PR ready.

No pushing to GitHub to look at my own diff before I'm ready for it to be there, and no leaving comments for myself. It's all local.

Try it

Node 22 or later and git, on macOS or Linux. If you don't want to point it at your own work yet, the welcome page seeds a complete made-up four-repo project - stacked PRs, review threads, agent replies, a merged stack - in about a second, with no network.

npx local-review init my-feature # write a project.yaml
npx local-review # serve the UI on localhost:5622
npx local-review init my-feature # write a project.yaml
npx local-review # serve the UI on localhost:5622

The docs are at local-review.edspencer.net, the code is on GitHub under MIT, and there's a longer tour here.

Share Post:

What to Read Next

Claude Code, meet Paddock

Paddock is a thin wrapper around Claude Code that runs it on a server and gives it a web UI — persistent, resumable chats you can reach from any laptop or phone, with forking, sub-agents, file sending and schedules on top. Here's why I built it and how it works.