A coding agent writes faster than you can read and hands you everything at once. μdiff turns that pile into a review: it shows the edits in batches as they land, remembers what you have already signed off, and lets you write comments and replacements against the lines themselves.
- Anything that produces a unified diff. μdiff reads it on standard input,
so
git diff,gh pr diff,diff -uon two loose files, or a patch from a mailing list all work the same. No repository required. - One binary, about 3 MB, with no runtime beside it.
- The review leaves as plain text. One key copies it in GitHub's suggestion syntax — paste it into your agent, into a pull request, into a message. No plugin, no protocol, no session to keep open.
Point μdiff at the directory the agent is editing and leave it open:
udiff --watch .Each time the agent pauses, its edits arrive as a new revision. { and } move
between revisions, Space marks a file you are happy with, c selects lines you
are not, and Shift+Y copies every note you left — across every revision,
skipping the files you marked reviewed.
Paste that into the agent and it has your review in a form it can act on. Nothing is written to disk and no repository is required, so it works on a scratch directory as well as on a checkout.
An hour of work is hard to remember in full. Read it before it becomes a commit:
git diff | udiff
git diff --staged | udiffThis is where the forgotten dbg!, the half-finished branch, and the file you
never meant to touch turn up.
git diff main..HEAD | udiff
gh pr diff 42 | udiff
cat changes.patch | udiffPress r on a line to write a replacement instead of a comment. Suggestions come
out in GitHub's own review syntax, so a review you pull down with gh goes back
up as a pull request comment unchanged.
Useful for generated output, configuration that has drifted, or a before and after:
diff -u old.rs new.rs | udiff
diff -ru old-dir/ new-dir/ | udiffGit can do the same for files outside a repository:
git diff --no-index --no-color -- old.rs new.rs | udiffNotes attach to the lines they belong to — a comment, or a replacement you write yourself:
Shift+Y copies them as plain text. A comment:
1. src/main.rs (old lines 3; new lines 3-4)
Selected diff:
-old
+new
Comment: this allocation is redundant
A suggested replacement, in GitHub's syntax:
2. src/main.rs (new lines 12)
Selected diff:
+ let value = compute().unwrap();
Suggested replacement:
```suggestion
let value = compute()?;
```
Comments live only for the current run. μdiff produces a review; it does not store one.
brew install aliev/tap/udiffmacOS and Linux:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/aliev/udiff/releases/latest/download/udiff-installer.sh | shWindows PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://github.com/aliev/udiff/releases/latest/download/udiff-installer.ps1 | iex"From source:
cargo install --path udiff --lockedPress ? for the full list. p finds a file by name, j/k and the arrows
move, s shows the diff side by side, b brings up the file list, Tab
switches to it, q quits.
Copying uses OSC 52, so the terminal has to allow clipboard access from programs.
μdiff asks the terminal what colour its background is and follows the answer.
Set UDIFF_THEME=light, dark or mono to decide for it — inside tmux or
screen, where the question cannot be asked, you will have to. NO_COLOR is
honoured and outranks both.
Feed μdiff an uncolored diff. Tools like delta emit terminal styling meant for
human eyes, which μdiff cannot parse — pipe it the original git diff instead.
diff and git diff --no-index exit with status 1 when they find differences.
A shell running with pipefail will report the whole pipeline as failed.
Start with ARCHITECTURE.md, then CONTRIBUTING.md. Release notes live in CHANGELOG.md. μdiff is available under the MIT License.