npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

diffing

v0.4.0

Published

local-first CLI for reviewing, navigating, and discussing git diffs with AI

Readme

diffing

A local-first code review tool and double-sided bridge designed for the modern AI coding agent workflow. Review AI-generated changes in a high-fidelity, GitHub-like web UI, leave inline comments, and hand them back to your coding agent to fix in real time — and review the agent's plan the same way before it writes any code, approving, rejecting, or requesting changes on specific lines and sections.


Quick Start

1. Install

Install diffing globally via npm:

npm install -g diffing

2. Run

Launch it within any active git repository:

diffing

This instantly spins up a local server, establishes an active repository watcher, and opens your default browser to an interactive code review dashboard.

Prefer the terminal? Add --tui for a native-Rust terminal UI — same review flow, no browser:

diffing --tui

[!WARNING] The TUI is experimental in v0.3.0. The interface, keymap, and server.json (mode: "tui") on-disk format may change in a minor release. The web UI is the supported path for production workflows. See Native Terminal UI (TUI) for the full feature set, keymap, and stability notes.

3. Update

Check if a new version is available on npm and upgrade instantly via the CLI:

diffing update

Web UI Review Dashboard

A local Hono-powered review server delivers a full-featured GitHub-like code review interface directly in your browser.

  • Split / Unified View — Toggle between side-by-side (split) and inline (unified) diff layouts via toolbar or keyboard shortcut m.
  • Syntax Highlighting — Powered by Shiki via @pierre/diffs, with high-fidelity highlighting for 200+ languages.
  • Interactive File Tree — Hierarchical file navigation sidebar with collapsible folders, viewed/unviewed tracking, and change-type indicators (added, modified, deleted).
  • Status Dashboard (Comment Tracker) — Bottom panel tracking open, replied, and resolved comments with filter tabs and click-to-navigate references to the relevant file and line.
  • Git Diff Stats — Toolbar displays repo name, branch, file count, and additions/deletions (+X/-Y) computed from the patch.
  • Server-Side State & Drafts Persistence — No browser storage is used. All settings, UI panels sizing, session states, and comment drafts are securely stored and persisted server-side in the project's global .diffing directory (and global settings inside ~/.config/diffing/settings.json).
  • Dynamic Font Customization — Pick any Google Fonts family or locally-installed system font for both UI typography and monospace code rendering, configurable via the settings font picker. Google-hosted families are fetched automatically as web fonts and render everywhere; local fonts are applied by name (see the note on custom fonts).
  • Resizable Panels — Drag-to-resize sidebar (240px–640px) and comment tracker panel (100px–600px). Panel states are instantly saved server-side for absolute consistency across browser sessions.
  • Skeleton Loading Screen — Full shimmer placeholder UI for toolbar, sidebar, search, tree nodes, and file diffs during initial load.
  • Image Diff Previews — Visual side-by-side comparison for added, changed, and deleted image files (PNG, JPEG, GIF, WebP, SVG, BMP, ICO, AVIF).

Themes

42+ built-in themes powered by Shiki, with instant switching and live preview.

| Category | Themes | |----------|--------| | GitHub Family | GitHub Dark, GitHub Light, GitHub Dark Dimmed, GitHub Dark High Contrast | | Popular Dark | Dracula, One Dark Pro, Monokai, Synthwave '84, Material Theme (Ocean/Palenight/Darker) | | Tokyo Night | Tokyo Night, Tokyo Night Storm, Tokyo Night Light | | Catppuccin | Mocha, Frappe, Macchiato, Latte | | Nord Family | Nord | | Nightfox Family | Nightfox, Nordfox, Duskfox, Terafox, Carbonfox, Dayfox, Dawnfox | | Rose Pine | Rose Pine, Rose Pine Dawn, Rose Pine Moon | | Solarized | Solarized Dark, Solarized Light | | VS Code | Dark+, Light+, Dark Modern, Light Modern | | Others | Andromeeda, Aurora X, Houston, Laserwave, Min Dark/Light, Night Owl, One Light, Plastic, Poimandres, Slack (Dark/Ochre), Vesper, Vitesse Dark/Light, Ayu Dark/Light |

  • Searchable Theme Modal — Press g t or use the toolbar to open a categorized, searchable theme picker with color swatches and live preview.
  • Dark/Light Dual Mode — Each theme maps to corresponding dark and light Shiki themes for accurate syntax highlighting in both modes.
  • Instant Switching — CSS transitions suppressed during theme changes for a snappy, lag-free experience.
  • Persistent Setting — Theme choice saved to ~/.config/diffing/settings.json and restored on next launch.

Rust-Powered Code Search (powered by fff)

Blazing-fast, native fuzzy code search integrated directly into the sidebar search palette via @ff-labs/fff-node:

  • Fuzzy File Search (Files scope) — Error-tolerant fuzzy matching on workspace paths using a native Rust engine.
  • Codebase Grep (Text scope) — Instant case-insensitive text search with full Regular Expression support.
  • Syntactic Symbol Search (Symbols scope) — Finds function declarations, class headers, type definitions, and variable assignments across JavaScript, TypeScript, Go, Rust, and Python (17+ language patterns).
  • Unified "All" Search — Concurrent search across files, text, and symbols with automatic deduplication.
  • Frecency Ranking — SQLite-backed history database remembers which files you open for specific queries, floating high-value results to the top.
  • "Changed Only" Filter — Restricts search scope exclusively to files changed in the active git diff.
  • Git Status Chips — Search results display git status indicators (modified, untracked, added, deleted, renamed).
  • Graceful Degradation — If the native Rust binary is unavailable, search reports as unavailable without crashing the server.
  • Auto-Indexing — The Rust engine maintains its own file system watcher for real-time index updates as the working tree changes.

Vim-Style Keyboard Navigation

Full keyboard-driven navigation with vim-like motions and a modal status bar:

Scrolling & Diffs

| Key | Action | |-----|--------| | j / k | Scroll down/up by 100px | | Ctrl+d / Ctrl+u | Scroll half-page down/up | | g g | Jump to top of diff | | G | Jump to bottom of diff | | m | Toggle split/unified view | | t | Cycle tab size (2 → 4 → 8) | | w | Toggle line wrap | | n | Toggle line numbers | | i | Cycle diff indicators | | I | Cycle inline diff type | | Cmd+Shift+P | Toggle preview mode in comments |

File Navigation & UI

| Key | Action | |-----|--------| | J / K | Jump to next/previous file | | v | Toggle file viewed/unviewed | | b | Toggle sidebar visibility | | / | Open text search | | s | Open symbol search | | g v | Open file browser | | g t | Open theme picker | | Cmd/Ctrl+K | Open global command palette | | Cmd/Ctrl+, | Toggle settings panel | | ? | Show shortcuts help modal |

A vim-style status bar at the bottom displays the current mode (NORMAL/INSERT), file path, and a help button. Multi-key sequences use an 800ms key buffer.


Native Terminal UI (TUI) — Experimental

[!WARNING] The TUI is experimental in v0.3.0. The interface, keymap, and on-disk format of server.json (mode: "tui") may change in a minor release before stabilisation. The web UI is the supported path for production workflows; please open an issue before depending on the TUI for CI / agent automation. The web review flow, plan review, and PR review are unaffected.

diffing --tui opens an opt-in native-Rust terminal interface that mirrors the web review dashboard — no browser, no Electron, no port. It's a leaf renderer in a new crates/diffing-tui/ binary: the Node CLI is still the single source of truth for arg parsing, lockfile discovery, and agent handoff, and the TUI reads the same ~/.diffing/<repo>/* state on disk and writes a server.json with mode: "tui".

The default diffing behaviour is byte-identical with and without --tui — the TUI is strictly opt-in. If the env cannot support a TUI (piped stdin, CI, no raw mode) or the binary is missing, you get a one-line stderr note and the normal git diff output. The web mode is also unaffected by the TUI build; the same diffing install serves either.

diffing --tui                       # Open the current working tree in the TUI
diffing --tui --staged              # Review staged changes in the TUI
diffing --tui HEAD~3                # Review working tree vs. 3 commits ago
diffing --tui main..feature         # Compare two branches in the TUI
diffing --tui -- -- src/            # Limit a TUI review to a directory

Stack — Rust 1.78+ workspace (crates/diffing-core/ shared lib + crates/diffing-tui/ binary), ratatui + crossterm for rendering, syntect for syntax highlighting, notify-debouncer-full for live updates.

Features

  • Unified diff render with a virtualised file card, syntect highlighter, and the same 8 Shiki-compatible colour themes as the web UI.
  • Vim-style file tree & keymapj/k/gg/G/J/K/Tab/w/t/m/?/ motions, plus c (new comment), e/r/x (edit / reply / resolve), ]/[ (next / previous thread), ? (help).
  • Full comment CRUD — mirrors src/lib/comments.ts byte-for-byte; the comment tracker at the bottom lists open / replied / resolved threads with click-to-jump navigation.
  • Multi-line tui-textarea form with markdown rendering in the preview pane.
  • Live updates via notify watcher on comments.json and the repo working tree — write a comment in another window and it appears immediately.
  • Send review & agent handoff — verdict radios + general-comment popover with a live XML preview. Submits via the same format_comments envelope as the web UI, copies to clipboard (pbcopy / wl-copy / xclip / xsel / clip.exe), and persists pending-review.xml. The agent-status indicator in the status bar mirrors the web UI's "Send to agent" connection dot.
  • Cross-platform — macOS, Linux, and Windows are all first-class. The TUI liveness probe uses kill(pid, 0) on Unix and tasklist /NH /FO CSV on Windows. Clipboard works on Wayland (wl-copy), X11 (xclip / xsel), macOS (pbcopy), and Windows (clip.exe / PowerShell Set-Clipboard).

Caveat — the TUI's "Send to agent" writes the review to disk + clipboard but does not actively unblock a long-polling diffing await-review; that requires a Node-side change in a follow-up. The web UI's send button remains the supported native handoff path. The pending-review.xml is still produced and the review session is still round-incremented — only the long-poll wake-up is missing.

Building the binary locally

pnpm build:tui               # debug build → target/debug/diffing-tui
pnpm build:tui --release     # release build → target/release/diffing-tui

The CLI auto-discovers the binary in the following search order: sibling of dist/cli.mjs, bin/, target/release/, target/debug/, then $PATH. A cargo build (debug) workflow is supported out of the box; you don't need --release just to use the TUI.


Console Startup Animations & Quotes

Every time you launch diffing in the terminal, it serves a highly polished, interactive greeting before the browser opens:

  • 256-Color Monochromatic Palettes — Beautifully rendered box outlines across 6 monochromatic themes (Cyan, Green, Magenta, Yellow, Blue, Orange) with custom faint, base, glow, and text hues.
  • Dynamic Startup Animations — Instantly runs one of 6 terminal-based micro-animations (Typewriter, Wave Reveal, Slide-In, Pulse Border, Glitch Noise, Matrix Rain) underneath the local server URL.
  • Motivational Developer Quotes — Settles to display one of 30 curated, funny, philosophical, or motivational developer quotes to kick off your review session.

Performance & Speed

Built from the ground up for a fast, fluid experience—even in large repositories:

  • Rust-Powered Search — Native engine handles indexing and querying outside the JS event loop.
  • Async Diff Execution — Server fetches unstaged, staged, and untracked diffs concurrently via Promise.all.
  • Web Worker Rendering@pierre/diffs uses a worker pool for syntax highlighting and diff computation off the main thread.
  • React.memo + useMemo — Extensive component memoization prevents unnecessary re-renders when files haven't changed.
  • useTransition — Settings changes (theme, diff style, font size) wrapped in startTransition for non-blocking UI updates.
  • Compositor-Only Resize — Sidebar and comment panel resize use GPU-composited transform guides; width/height committed only on mouseup for 60fps feel.
  • Shiki Pre-Warming — Highlighter engines preloaded on theme change for instant first paint.
  • Large Buffer Support — Git operations use 50–100MB max buffer to handle large diffs.
  • Object Reference Stability — Diff metadata reuses previous object references when file contents haven't changed (JSON comparison of hunks).
  • Stale Project Cleanup — Project storage directories older than 14 days or with missing repo paths are automatically purged.

Real-Time Communication

Bidirectional, event-driven sync between the browser UI and connected AI agents via Server-Sent Events (SSE):

┌──────────────┐     SSE (change/comments/agent-status)     ┌──────────────┐
│              │◄───────────────────────────────────────────►│              │
│   Browser    │                                             │   AI Agent   │
│     UI       │     ┌─────────────────────────────┐        │   (CLI/MCP)  │
│              │     │       comments.json          │        │              │
│              │     │  (FileCommentStore on disk)  │        │              │
└──────┬───────┘     └──────────┬──────────────────┘        └──────┬───────┘
       │  user writes comment    │                                  │
       │ ──────────────────────► │    fs.watch detects change       │
       │                         │ ───────────────────────────────► │
       │                         │    agent posts reply             │
       │  SSE broadcasts toast   │ ◄────────────────────────────── │
       │ ◄───────────────────────│                                  │
  • Single SSE Endpoint (/api/live) — Multiplexed event stream with named events: change (working tree), comments (store updated), agent-status (agent connect/disconnect/send), heartbeat (15s keep-alive).
  • File System Watcherfs.watch on repo root (recursive, 200ms debounce) triggers live diff refresh on working tree changes. Skips .git, node_modules, dist, and .changeset.
  • Comment Store Watcherfs.watch on comments.json (120ms debounce) broadcasts updates when agents or humans write comments externally.
  • Agent Activity Toasts — Real-time toast notifications when an agent posts a reply, showing model name, file path, and body preview. Clickable to jump to the file; auto-dismisses after 8 seconds.
  • Agent Status Indicator — Green dot on the "Send to agent" button when an agent process is connected and waiting (via SSE agent-status events).
  • Bidirectional Sync — User adds comments in UI → saved to comments.json → watcher → SSE broadcast → agent picks up. Agent posts reply → written to comments.json → watcher → SSE → UI toast.

AI Agent Collaboration (Handoff Protocol)

diffing solves the friction of copy-pasting code review notes into LLM chat boxes. It establishes an "agent waits, human releases" pipeline using a robust, port-agnostic lockfile mechanism.

1. The agent runs a blocking command/tool and enters sleep mode.
2. You review code in your browser, leave inline comments, and click "Send to agent".
3. The agent wakes up instantly, receives comments as structured XML, applies edits, and posts replies.

A. CLI Integration (For any terminal-based agent)

The diffing binary acts as a port-agnostic CLI client. It automatically discovers the running server by reading a local repository lockfile:

diffing await-review                 # Block process until you click "Send to agent"; outputs comments as XML
diffing comments [--open] [--json]   # One-shot query of the comments database
diffing reply <id> --body "..."     # Post an agent response or explanation
diffing resolve <id>                 # Mark a comment resolved, updating the UI live
diffing url                          # Retrieve the active server base URL

# Plan review (review a markdown plan before any code is written)
diffing plan submit <file> [--title T] [--model M] [--id <id>] [--wait]   # Submit/resubmit a plan; prints its id
diffing plan await [--timeout N]     # Block until the human approves/rejects/requests-changes; outputs the verdict XML
diffing plan list [--json]           # List submitted plans with their verdicts
diffing plan show [<id>] [--json] [--version N]   # Show one plan as <plan-review> XML (latest if omitted; use --version to read a historical body)
diffing plan versions <id> [--json]  # List every submitted version of a plan, oldest-first (current marked with `*`)
diffing plan reply <commentId> --body "..."   # Reply to an inline plan comment
diffing plan resolve <commentId>     # Mark a plan comment resolved

B. Model Context Protocol (MCP) Server

If your agent supports MCP (such as Cursor, Claude Desktop, or Gemini), configure diffing as a stdio-based MCP server. No ports need to be configured:

{
  "mcpServers": {
    "diffing": {
      "command": "diffing",
      "args": ["mcp"]
    }
  }
}

Exposes tools directly to your agent for both review flows — diff review: await_review, list_comments, reply_to_comment, resolve_comment; and plan review: submit_plan, await_plan_review, list_plans, get_plan, get_plan_versions, get_plan_version, reply_to_plan_comment, resolve_plan_comment.

C. Agent Skills

You can install diffing skills directly into your AI coding assistant:

npx skills add ahmedragab20/diffing

Provides commands to coordinate reviews:

  1. /diffing-start-review — Launches the review server.
  2. /diffing-finish-review — Blocks the agent using await-review until comments are sent, then applies requested edits.
  3. /diffing-review — Combined launch-and-wait flow.
  4. /diffing-plan-review — Submit a markdown plan, block until the human approves/rejects/requests changes, then proceed or revise.

Send Review Popover

A GitHub-style "finish your review" popover with inline editing of each comment, an optional general/overall comment, and a visual indicator when an agent is waiting. The "Copy comments" toolbar button serializes all comments to the XML spec and copies them to the clipboard.

Port-Agnostic Discovery

A per-repo lockfile (server.json) in ~/.diffing/<repo-hash>/ enables all subcommands and MCP tools to discover the server's port with zero configuration. Stale or crashed server locks are automatically detected and treated as dead via process.kill(pid, 0).

Monotonic Round Sequencing

A ReviewSession class with a monotonic round counter and race-guard logic ensures that if a "Send to agent" lands between polling intervals, the cached payload is delivered immediately. Multiple agents can block on the same review session simultaneously—all are released together on send.


Plan Review

Review any agent plan — not just code. When an AI agent produces a plan (an implementation outline, a design proposal, a migration strategy), diffing renders the markdown line-by-line so you can comment on specific lines or sections and approve, request changes, or reject it — then hands the structured verdict back to the waiting agent. It's the "agent waits, human releases" handoff, applied before any code is written.

1. The agent submits a markdown plan and blocks (diffing plan submit … --wait).
2. You open the "Plans" tab, read the plan, and comment on lines/sections.
3. You click Approve / Request changes / Reject (with an optional overall note).
4. The agent wakes instantly, receives the verdict + comments as <plan-review> XML,
   and proceeds, revises-and-resubmits, or stops accordingly.
  • Renders any markdown plan — the plan body is shown via @pierre/diffs with full syntax highlighting and line numbers, so it's addressable like a diff.
  • Line, range & section comments — hover the gutter + or select a line range to comment; each comment auto-captures its enclosing markdown heading (section) and the exact anchored text for the agent.
  • General comments — attach notes scoped to the whole plan.
  • Three-way verdict — Approve / Request changes / Reject, GitHub-style, with an optional overall comment. Resubmitting a revised plan (same id) bumps the version and re-opens it for review.
  • Browse plan versions — every submitted body is kept on disk, oldest-first. A version dropdown next to the v{n} chip switches the viewer to any past version; comments are filtered to those anchored to the version you're reading; a "viewing v{N} of v{M}" banner makes the historical context obvious. Available from the CLI (diffing plan versions <id>, diffing plan show <id> --version N), MCP (get_plan_versions, get_plan_version), and the HTTP API (GET /api/plans/:id/versions, GET /api/plans/:id/versions/:n).
  • Live "Plans" badge — the diff toolbar shows a badge counting plans awaiting your review, with a green dot when an agent is connected and waiting.
  • Same channels everywhere — drive it from the CLI (diffing plan …), the MCP tools (submit_plan, await_plan_review, …), or the HTTP API (POST /api/plans, POST /api/plans/:id/decision, GET /api/plan-review/await).

Plan Review XML Specification

When a plan verdict is handed to a waiting agent, it is serialized into a self-documenting <plan-review> envelope:

<plan-review>
  <instructions>…how to act on the verdict; how to reply/resolve/resubmit…</instructions>
  <plan id="…" title="…" version="2" decision="changes-requested" decided-at="2026-05-29T18:52:56.053Z">
    <decision-summary><![CDATA[The reviewer REQUESTED CHANGES. Revise the plan…]]></decision-summary>
    <decision-comment><![CDATA[Tighten the Phase 2 scope.]]></decision-comment>
    <plan-body><![CDATA[# My Plan
## Phase 1
…full markdown of the plan being reviewed…]]></plan-body>
    <comments>
      <comment id="c1" line="4" section="Phase 1" status="open" created-at="2026-05-29T18:52:29.557Z">
        <context><![CDATA[Do the first thing]]></context>
        <body><![CDATA[Clarify what "the first thing" is.]]></body>
        <replies>
          <reply id="r1" created-at="…" role="agent" model="claude-opus-4-8"><![CDATA[Will do — splitting into 1a/1b.]]></reply>
        </replies>
      </comment>
    </comments>
  </plan>
</plan-review>

Reviewing a GitHub PR

diffing can open a GitHub PR in the same diff UI you use for the working tree, and push your review back to GitHub when you're done. The "Send to agent" handoff is structurally absent in PR mode — there's no way to accidentally route a PR review to a coding agent.

# All of these open PR #1234 in the current repo:
diffing "gh pr 1234"
diffing --gh-pr 1234

# Full URL form:
diffing "gh pr https://github.com/ahmedragab20/diffing/pull/1234"
diffing --gh-pr https://github.com/ahmedragab20/diffing/pull/1234

# owner/repo#N shorthand (skips the cwd-repo check):
diffing "gh pr ahmedragab20/diffing#1234"

The PR diff loads in the existing <DiffViewer> / <FileTree> machinery. Existing review comments on the PR are fetched and shown as a read-only summary strip below each file so you can see what was already said before adding your own. Comments you write are kept visually distinct.

When you click Submit to GitHub, diffing builds a POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews payload and POSTs it to GitHub. Multi-line comments are expanded to N single-line comments with a [part N/M] prefix. Existing comments are never re-POSTed — only the new ones you wrote in this session.

Headless subcommands

For CI / agent use, the same flow is exposed as a gh subcommand with no UI:

# Submit the current in-progress review to GitHub.
diffing gh pr-review 1234 --decision request-changes --body "Please address the range"

# Dump PR metadata (title, owner, head SHA, existing comments) as JSON.
diffing gh pr-fetch 1234

# List the PR-mode comments in this diffing session (mirrors `diffing comments`).
diffing gh pr-list-comments

# Show the active PR session (ref, owner/repo#n, comment count, submitted status).
diffing gh status

Authentication

The submit path uses the same precedence as the rest of the GitHub ecosystem:

  1. gh CLI — preferred; uses your existing gh auth login session.
  2. Token env var$GH_TOKEN, then $GITHUB_TOKEN, then $GITHUB_API_TOKEN (any of the three).
  3. If neither is available, the submit fails with a clear one-line message telling you to run gh auth login or set $GITHUB_TOKEN.

The gh binary is only used for the submit and refresh steps; the diff itself is rendered locally, so PR review works offline once the session is open.

Storage

PR-mode state lives in pr-session.json (in the per-repo ~/.diffing/<repo>-<hash>/ directory) — a separate file from comments.json and plans.json, so a local review and a PR review can coexist without colliding.


Inline Comment System

Rich, real-time comment threads directly on diff lines:

  • Inline Threads — Hover and click the + button on any addition or deletion line to start a thread. Supports markdown (GFM + line breaks) with syntax-highlighted fenced code blocks.
  • Multi-Line Comments — Select a line range to comment on an entire block of code.
  • File-Level Comments — Add general comments scoped to the entire file without targeting a specific line.
  • Comment Drafts — Draft system (diffing-draft-* keys) with 7-day TTL, stored in the global .diffing folder so drafts survive page refreshes without any browser storage footprint.
  • Agent Attribution — Replies carry role (user/agent) and the agent's model name for clear attribution.
  • Suggestion Application — Parse ```suggestion code blocks from comment bodies and apply them to the file in one click via POST /api/comments/:id/apply-suggestion.
  • Full CRUD API — REST endpoints for creating, reading, updating, and deleting comments and replies.

Inline Diff Viewer Settings

Fine-grained control over how diffs are rendered:

| Setting | Options | Description | |---------|---------|-------------| | Inline Diff Type | word (default), word-alt, char, none | Pinpoint exactly what changed inside a modified line | | Diff Indicators | classic (+/−), bars, none | Gutter markers for added and deleted lines | | Line Numbers | on / off | Toggle gutter line numbers | | Line Wrap | on / off | Soft-wrap long lines instead of horizontal scrolling | | Hunk Separators | simple, metadata, line-info, line-info-basic | Style of the separator bar between diff hunks | | Line Hover Highlight | both, line, number, disabled | Which element highlights on hover | | Font Size | 11px – 16px | Configure globally | | UI Font | Any system or Google font (default Geist Mono) | Customize typography for the Web UI layout | | Mono Font | Any system or Google font (default JetBrains Mono) | Customize typography for code/diff block displays | | Tab Size | 2 / 4 / 8 | Default tab width (overridden per-file by EditorConfig) | | Expandable Context | expandContextByDefault, collapsedContextThreshold (default 10 lines), expansionLineCount (default 20) | Control how collapsed context regions behave | | Haptic & Sound Feedback | on / off | Tactile feedback via web-haptics and synthesized audio cues (click, toggle, navigate, open, close, resolve, send, error) |

All settings persist to ~/.config/diffing/settings.json and the UI updates are wrapped in useTransition for non-blocking responsiveness.

A note on custom fonts

Google-hosted families (e.g. Fira Code, Source Code Pro, IBM Plex Mono, Roboto Mono) are fetched automatically as web fonts and render in any browser. A locally-installed font — a Nerd Font, or a commercial font like Dank Mono — is applied by name and renders only if it is installed on your machine and your browser allows pages to use local fonts.

Privacy-hardened browsers block this: Brave, with Shields / "Block fingerprinting" enabled (the default), refuses to render uncommon local fonts as an anti-fingerprinting measure, so the selection silently falls back to the default monospace even though it is installed. To use a local-only font there, either pick a Google-hosted equivalent, or open Shields for the diffing site, set fingerprinting to Allow all, and reload.


Merge Conflict Resolution

When your repository is in a merge state (.git/MERGE_HEAD detected):

  • Conflict Banner — A prominent warning banner appears in the toolbar indicating the repo is in a merge conflict state.
  • UnresolvedFile Rendering — Conflicted files are rendered using @pierre/diffs's UnresolvedFile component with color-coded conflict markers.
  • Custom Action Buttons — For each conflict region, choose Accept Current, Accept Incoming, or Accept Both.
  • Save & Stage — After resolving all conflicts in a file, click Save & Stage to write the resolved content and git add it in one step.
  • Merge Status APIGET /api/merge-status returns conflict state and lists conflicted files via git diff --name-only --diff-filter=U.

Hunk Revert & History

  • Revert Individual Hunks — Undo a single hunk from the working tree via POST /api/revert-hunk using git apply --reverse.
  • Blame & History — View git blame for deleted lines and recent commit history for any file via GET /api/hunk-history, showing who authored deleted code and when.

Advanced Git Operations

  • File Open in IDE — Open any repo file in VS Code, Zed, Vim, Neovim, or the system default editor via POST /api/open-file. Configurable in settings.
  • File Save & Stage — Write file contents to disk and optionally git add in one call via POST /api/save-file.
  • Repository File ListerGET /api/repo-files lists all known files (tracked + untracked, respecting .gitignore).
  • File Content RetrievalGET /api/file-content and GET /api/file-text return old (HEAD) or new (working tree) file versions as binary buffers or JSON text.
  • EditorConfig Integration — Respects your local .editorconfig rules (tab_width, indent_size) for accurate, per-file tab sizing that overrides the default setting.

Git Diff Drop-in Compatibility

diffing is designed as a seamless, full drop-in replacement for git diff. It features a comprehensive option parser that understands standard git revisions, options, and pathspecs, forwarding them directly to your local git engine.

Whether you are comparing branches, reviewing staged changes, or filtering specific directories, simply swap git diff for diffing to instantly elevate your review into a premium, interactive browser interface:

diffing                          # Review working tree changes in the browser UI
diffing --staged                 # Review staged changes (drop-in for git diff --staged)
diffing HEAD~3                   # Review working tree changes against 3 commits ago
diffing main..feature            # Compare two branches (drop-in for git diff main..feature)
diffing -- --cached -- src/      # Staged changes specifically in the src/ directory

Intelligent Output Modes (TTY Auto-Detection)

To integrate flawlessly with your existing developer shell workflows, build pipelines, and command scripts, diffing automatically resolves the optimal output mode based on how stdout is directed:

  • Web Mode (Default for interactive TTY): When executed in an interactive terminal session, it boots the local Hono review server, registers the repository lockfile, and opens your default browser.
  • Terminal Mode (Default for pipes, redirects, or non-TTY): When output is piped (e.g. diffing | grep "const") or redirected to a file, it falls back to behave exactly like git diff, streaming clean, standard unified diff patch text directly to standard output and exiting.

[!TIP] Any standard output control or format-related flags (such as --raw, --numstat, --stat, --exit-code, --quiet, or -o) will automatically force Terminal Mode fallback.

[!TIP] For a full list of all git option categories (algorithms, whitespace ignoring, context lines, word-level diffs, moved/copied detection, and path filtering) supported by diffing, see the CLI Reference Manual.

diffing show — Review a Commit's Changes (Drop-in for git show)

diffing <sha> runs git diff <sha>, which means "diff between <sha> and the working tree" — not the changes that commit introduced. If the working tree matches <sha>, the patch is empty and the file list renders blank.

To review the changes of a commit, use the new show subcommand. It mirrors git show and surfaces each commit's metadata (subject, author, date, message body) above the diff in the web UI:

diffing show HEAD              # Review the tip commit's metadata + diff
diffing show HEAD~3..HEAD      # Review the last 3 commits as a series
diffing show v1.0              # The commit a tag points to
diffing show abc123 def456     # Two specific commits, oldest-first
diffing show HEAD -- src/      # Limit a commit review to a directory
diffing show HEAD~2..HEAD --terminal   # Stream `git show` to your terminal

show accepts every form git show understands (single commit, range, tag, branch tip, multiple SHAs) and is strictly opt-in — diffing <sha> keeps its current git diff <sha> semantics so existing muscle memory and scripts are unaffected.


Integration & Configuration

  • Persistent User Settings — Settings saved to ~/.config/diffing/settings.json, loaded on startup, synced to server via PUT /api/settings.
  • Custom Host/Port--host 0.0.0.0 exposes the review dashboard to the local network; --port <port> overrides random port selection.
  • --no-open Flag — Prevents auto-browser opening on server start.
  • Git Config Alias — Register diffing as git review via ~/.gitconfig.
  • Shell Aliases.zshrc/.bashrc examples: gd="diffing", gds="diffing --staged", gda="diffing & diffing await-review".
  • Configurable Browser & IDE — Choose which browser to auto-open (Chrome, Firefox, Edge, Brave, or system default) and which IDE to use for file opening (VS Code, Zed, Vim, Neovim, or system default).
  • Graceful ShutdownSIGINT/SIGTERM handlers remove the server lockfile on exit.

Comment XML Specification

When review comments are exported or streamed to a waiting agent, they are serialized into an optimized, self-documenting XML structure equipped with CDATA blocks:

<code-review-comments>
  <instructions>
    You are an AI coding assistant receiving a structured list of code review comments to address.
    For each file, review the inline comments and apply the changes requested.
    - Target lines are specified by the "line" attribute (e.g. line="42" for single lines, line="42-45" for multi-line blocks, or line="file" for file-level notes).
    - "side" indicates whether the comment is on "additions" (new code) or "deletions" (old code).
    - "status" indicates whether the comment is "open" or "resolved". Only address "open" comments.
    - The <code> block contains the code context at the reviewed lines.
    - The <body> tag contains the review feedback or request.
    
    HOW TO REPLY OR MARK AS RESOLVED:
    - Prefer using the diffing CLI or MCP server tools (reply_to_comment / resolve_comment).
    - CLI: `diffing reply <id> --body "..."`
    - CLI: `diffing resolve <id>`
  </instructions>

  <!-- [Optional] High-Level General Review Comment -->
  <general-comment>
    <![CDATA[Please refactor the parsing module to improve reliability.]]>
  </general-comment>

  <file path="src/utils/parser.ts">
    <!-- [Example A] Multi-Line Selection Addition Comment -->
    <comment id="c1" line="42-45" side="additions" status="open" created-at="2026-05-24T22:00:00.000Z">
      <code><![CDATA[
+ const parsedToken = tokenize(input);
+ if (parsedToken.type === 'EOF') {
+   return null;
+ }
]]></code>
      <body><![CDATA[Refactor this tokenization block to check for undefined inputs as well.]]></body>
      <replies>
        <reply id="r1" created-at="2026-05-24T22:05:00.000Z" role="agent" model="claude-3-5-sonnet">
          <![CDATA[I agree, I will add a guard clause for undefined.]]>
        </reply>
      </replies>
    </comment>

    <!-- [Example B] Whole-File General Comment -->
    <comment id="c2" line="file" side="additions" status="open" created-at="2026-05-24T22:08:00.000Z">
      <body><![CDATA[This parser module needs additional unit tests to cover negative bounds.]]></body>
    </comment>
  </file>
</code-review-comments>

Security

  • Path Traversal Prevention — All file operations validate paths against the repository root, rejecting .., null bytes, absolute paths, and URL-encoded bypass attempts.
  • 403 Forbidden Responses — File operations (open-file, save-file, revert-hunk, hunk-history) reject paths outside the repo root.
  • Attachment Isolation — Uploaded attachments are restricted to ~/.diffing/<repo>/attachments/.
  • Client Directory Isolation — Static file serving resolves against the client directory and rejects paths outside it.
  • XSS Prevention — HTML is escaped before markdown rendering; marked is used for safe HTML generation.
  • Repo Path Verificationrepo_path.txt is written to storage directories for cross-checking.

Deep-Dive Documentation

For advanced features, internal API endpoints, sequence specifications, and configuration parameters, explore the complete guide:

[!IMPORTANT] Read the CLI & Protocol Reference Manual for detailed descriptions of:

  • TTY Auto-Detection and Output Mode resolution.
  • The port-agnostic discovery lockfile mechanics.
  • Monotonic sequence round synchronization for race-free polling.
  • Full Web API endpoints schema (GET /api/review/await, POST /api/comments, etc.).
  • Custom git config shell aliases.

Landing Page


👉🏻 The project was intially forked from wong2/diffx

License

MIT