Compare any two Git endpoints — two branches of one repo, or branches of two different repos in a multi-root workspace — with a changed-file tree, commit history, and one-click built-in diffs, all in a dedicated sidebar.
vscode-diff Next is the actively maintained product on top of the classic Diff Visualizer lineage. The upstream git history stays in this repo so the fork trail is honest. Packaging, security posture, docs, and day-to-day tooling follow the same bar as vscode-pdf Next.
- 🔀 Branch compare without leaving the editor. Pick two endpoints
(
{folder} · {ref}); see every changed path and the commits between them. - 🗂️ Cross-repo compare. Each side can be a different repository in your
workspace — ideal for comparing versioned checkouts (
app-2.5vsapp-2.6) that don't share a git history. - ✅ Honest file status. Status comes from
git diff --name-status(A/M/D/R/C, NUL-safe parsing, rename detection) — not guessed from insert/delete counts. Renamed files diff old name ↔ new name. - 🕘 Commit history. Searchable list for the
base..targetrange; subject and body exactly as git wrote them. - 🔒 Hardened. Nonce-based webview CSP, untrusted-input validation on every ref and path crossing the webview boundary, no shell execution (refs and paths are passed to git as discrete arguments).
| Feature | Status |
|---|---|
| Dual targets: any two workspace repos + branches | ✅ |
| Session tabs: hold several compares at once | ✅ |
| Folder-then-branch picker (searchable, not a short OS list) | ✅ |
| SCM-style list (M / U / D / R / C) with foldable groups | ✅ |
| M → side-by-side diff; U/D → single side; R → old ↔ new | ✅ |
| Images and PDFs open in their viewer, changed ones side by side | ✅ |
| Open Target 2 worktree file (↗) | ✅ |
| Editable diff + per-change revert arrow (→) when Target 2 is checked out | ✅ |
| Discard: apply Target 1 → Target 2 worktree (binary-safe) | ✅ |
| Commit history + search (same-repo only, capped at 1000) | ✅ |
| Persist open tabs + last pair + list font size | ✅ |
| Unicode / unusual filenames | ✅ (-z parsing) |
| Windows / Linux / macOS | ✅ (git on PATH) |
Requires VS Code 1.95+ and Git on PATH. For the install scripts, the
VS Code CLI (code) must be on PATH too. Prebuilt VSIX files are attached to
GitHub Releases.
Windows (PowerShell):
cd path\to\vscode-diff-next
npm install
.\update-extension.ps1
# or: .\update-extension.ps1 -NoRestartLinux / macOS:
cd path/to/vscode-diff-next
npm install
chmod +x ./update-extension.sh
./update-extension.sh
# or: ./update-extension.sh --no-restartCross-platform npm wrappers: npm run update, npm run update:norestart,
npm run update:dev.
Dev loop (Extension Development Host, no VSIX):
npm run update:dev
# other terminal: npm run watch
# Extension Host: Reload Window after each changenpm run compile
npm run package # bundles production deps (simple-git); do not use --no-dependencies
code --install-extension diff-next-<version>.vsix --forceMarketplace id once published: RicardoFrantz.diff-next.
- Click vscode-diff Next in the activity bar.
- Use tabs to keep more than one compare open (
+adds a tab; each tab is one pair). Drag a tab to reorder the strip, orCtrl+Shift+←/→from the keyboard — the order is remembered. Double-click (orF2) renames a tab; clearing the name restores thefolder · folderlabel. Right-click for Rename, Duplicate, Close, Close others, and Close to the right. - Pick each side with the folder-then-branch picker: click a target,
choose a workspace folder (type to filter), then a local branch of
that folder. A side that already has a folder starts on its branches, and so
does the second box once the first one has a folder — comparing two
branches of one repo is two clicks.
←goes back to folders, and an explicit folder on that side is never overridden. A new tab starts on the folder you were last in. Remotes are hidden. The two sides can never be the same endpoint. - Click a Modified (M) file for a side-by-side diff; Renamed (R) diffs the old path against the new one. Under the two targets, Compare view has independent on/off toggles (Wrap, Ignore spaces, Two columns, Fold same, Pin tab, Moved code) plus Prev/Next file. They apply to the editor that opens. The folder picker closes once you pick a branch.
- Click a New (U) or Deleted (D) file for a single view.
- Click a group header (Modified / New / Deleted / …) to fold that section.
- Same-repo only: searchable commit history between the tips.
↺applies Target 1's version onto Target 2's worktree (with confirmation);↗opens the Target 2 worktree file.
Command Palette: vscode-diff Next: Compare Branches (editor-area panel).
To leave a note for Claude / Codex: select text in the compare or in any file
on disk. A strip opens on those lines: Save, then the five tags
(fix improve explain re-check discuss, with fix armed),
then Delete. Type the note — the armed tag rides in the box as {fix} —
and press Enter. Esc discards it. Clicking anywhere outside the selection hands
the keyboard straight back to the editor.
A saved range turns amber: the text is washed, the gutter gets a rail, the
scrollbar gets a mark, and a {fix} chip sits at the end of the range. It
reads on top of the green of an added line, so you can see at a glance which
parts of a diff you have already been through. Hover the amber to read the note
or delete it. The first save creates myfile-rev.json next to myfile.md.
Later notes append to the same file:
[
{
"selected_text": "the highlighted code\ncan span lines",
"range": "42-45",
"tag": "fix",
"comment": "your note"
}
]When Target 2 is the checked-out branch of its repository and the file
exists on disk, the diff opens against the working-tree file instead of a
read-only snapshot (the title ends in · Working Tree). That makes the right
side editable, so VS Code's built-in diff editor shows its native per-change
gutter arrow (→) — click it to revert just that change to Target 1's version,
then save (Ctrl+S) to persist. F7 / Shift+F7 (and the title-bar arrows)
jump between changes in any diff.
Notes:
- The arrow is VS Code's own
diffEditor.renderMarginRevertIcon(default on). - The right side shows the file as it is on disk, including uncommitted local edits; the file tree still lists changes between the two committed refs, so a reverted-and-saved file stays listed until you commit.
- When neither target is checked out, diffs stay read-only snapshots as before.
Set
diff-next.diffAgainstWorktree: falseto always get read-only diffs. - The
+(stage hunk) gutter button is exclusive to VS Code's built-in git SCM views and can't appear in extension-opened diffs — save your revert, then stage it from the Source Control view.
- No shell. All git invocations go through
simple-gitwith discrete arguments — refs and paths are never interpolated into a command line. - Untrusted webview input. Every ref and path received from the webview or
from virtual-document URIs is validated: refs must not look like git flags
(no leading
-, no git-forbidden characters); paths must be repo-relative with no..escapes. Worktree writes are additionally checked to resolve inside the target repository root. - Strict CSP. The webview allows only nonce-tagged scripts; error output is rendered as text, never HTML.
- No telemetry, no network calls. Everything runs against your local repos.
See SECURITY.md for reporting.
| vscode-pdf Next | vscode-diff Next | |
|---|---|---|
| Repository | ricardofrantz/vscode-pdf-next |
ricardofrantz/vscode-diff-next |
| Display name | vscode-pdf Next |
vscode-diff Next |
| Package name | pdf-preview-next |
diff-next |
| Install id | RicardoFrantz.pdf-preview-next |
RicardoFrantz.diff-next |
| Command prefix | vscode-pdf Next: … |
vscode-diff Next: … |
Publisher for both: RicardoFrantz.
See docs/DEVELOP.md. Short map:
src/host/DiffHost.ts shared webview host + git message handling
src/services/gitService.ts git façade via simple-git (-z parsers, validation)
src/webview/ UI (vanilla JS, injected into one HTML file)
update-extension.ps1/.sh compile → package → install → restart
Checks: npm run lint, npm run compile, npm run smoke:paths. CI runs all
three plus a VSIX package on Linux, macOS, and Windows. Releases are tag-driven
— see docs/RELEASING.md.
Uninstall the old extension, install this one. Same job: two branches, file tree, commits. New work lands here only.
Fork of Diff Visualizer (lxliang912 / lkcoffee). See NOTICE and LICENSE.
