mark is a fast, keyboard-first terminal Git diff reviewer. It opens local
changes, commits, patches, pager input, difftool pairs, and GitHub pull requests
in the same focused review UI.
A focused Rust change in Mark, rendered in Catppuccin Mocha. Reproduce it with this VHS tape.
- Review any changeset. Open the worktree, revision ranges, commits, patch files, stdin, difftool pairs, or a GitHub pull request by number or URL.
- Move without waiting. Jump between files, hunks, matches, the top, or the bottom while rendering only the visible viewport.
- Find the relevant change. Filter files, grep the diff, expand context, or switch from hunks to the full file without leaving the reviewer.
- Leave review context. Move the highlighted annotation row across the diff to add inline annotations one at a time or in sticky batch mode.
- Work the way you want. Toggle split and unified layouts, choose a built-in or custom theme, customize keybindings, and open the focused code in your editor.
- Fit into Git. Use Mark directly, as
core.pager, or as a Git difftool. Local worktree sessions can watch for changes and reload in place.
The supported install path is the shell installer for macOS and Linux on
aarch64 and x86_64:
curl -fsSL https://raw.githubusercontent.com/phongndo/mark/main/scripts/install.sh | shHomebrew, mise, Cargo, and other package-manager installs are deprecated for now. Reinstall with the command above if you used one of those paths before.
Installer environment variables use the MARK_ prefix:
curl -fsSL https://raw.githubusercontent.com/phongndo/mark/main/scripts/install.sh | MARK_VERSION=0.10.6 sh
curl -fsSL https://raw.githubusercontent.com/phongndo/mark/main/scripts/install.sh | MARK_INSTALL_DIR=/usr/local/bin shUpdate a curl-installed binary in place:
mark update
mark update --target-version 0.10.6Nightly builds are published from main as a prerelease channel. Switch the
installed mark binary to nightly, then back to stable, with:
curl -fsSL https://raw.githubusercontent.com/phongndo/mark/main/scripts/install.sh | MARK_VERSION=nightly sh
mark updateOnce on stable, switch to nightly again with:
mark update --target-version nightlyNightly binaries report their channel and build commit in mark --version.
mark # review current worktree changes
mark main # review current branch against main
mark main feature # review a revision range
mark show HEAD~1 # review one commit
mark review 123 # review GitHub PR #123 from the current repo
mark patch changes.diff # review an existing patch file
git diff | mark pager # use mark as a diff pagerPlain mark is a shortcut for mark diff. While reviewing, move the cursor
with Vim-style motions and counts such as 3j. Press v or V for linewise
Visual mode, select a range, and press Enter to annotate it; Enter also
annotates a single line, hunk header, or file header. Use y to copy annotations and
Shift-Q to copy them and quit (q quits without submitting them).
Mark keeps the hot path viewport-bounded instead of rebuilding the entire screen model for every action. That matters on ordinary reviews, and it keeps navigation responsive when a generated change or pull request becomes enormous.
A committed Apple Silicon reference run measured the synthetic one-million-row diff fixture as follows:
| Diff | Load | Open | Grep | Random-scroll max | RSS increase |
|---|---|---|---|---|---|
| 1,000,000 rows / 74.0 MB | 20.6 ms | 20.8 ms | 68.0 ms | 87 µs | 112 MB |
These are reference-machine benchmark results, not latency promises for every machine or repository. The fixture, commands, memory accounting, and 10-million- row local run are documented in the mega-diff performance report.
These tools solve related but different problems. Mark, Tuicr, and Hunk are interactive reviewers, delta is primarily a syntax-highlighting pager, and Difftastic is a structural diff engine.
| Built-in capability | Mark | Tuicr | Hunk | delta | Difftastic |
|---|---|---|---|---|---|
| Interactive multi-file review UI | Yes | Yes | Yes | — | — |
| Split / side-by-side view | Yes | Yes | Yes | Yes | Yes |
| Runtime layout switching | Yes | Yes | Yes | — | — |
| Inline review annotations | Yes | Yes | Yes | — | — |
| Persistent review sessions | — | Yes | — | — | — |
| GitHub review submission | — | Yes | — | — | — |
| GitLab merge request review | — | Yes | — | — | — |
| Live worktree or file reload | Yes | — | Yes | — | — |
| File filtering | Yes | Yes | Yes | — | — |
| In-diff text search | Yes | Yes | — | — | — |
| Direct GitHub pull request review | Yes | Yes | — | — | — |
| Git pager workflow | Yes | — | Yes | Yes | — |
| Git difftool / external-diff workflow | Yes | — | Yes | — | Yes |
| Native non-Git VCS support | — | Jujutsu, Mercurial | Jujutsu, Sapling | — | — |
| Structural, syntax-aware diff algorithm | — | — | — | — | Yes |
| Syntax highlighting | Yes | Yes | Yes | Yes | Yes |
The table compares documented, built-in workflows. Each tool can be composed with other Git and shell commands beyond what is listed here.
Use mark pager as a Git pager for git diff and git show output:
git config --global core.pager "mark pager"Use mark difftool as a Git difftool for Git-provided file pairs:
git config --global diff.tool mark
git config --global difftool.mark.cmd 'mark difftool -- "$LOCAL" "$REMOTE" "$MERGED"'This repository includes a separate pi-mark Pi package. It adds a /mark
command to Pi and shells out to an already-installed mark binary. It does not
bundle the CLI.
pi install npm:pi-markThe slash command moved from /diff, /show, and /patch to /mark with
subcommands (/mark diff, /mark show, /mark patch). PI_DX_BIN is now
PI_MARK_BIN.
See pi-mark/README.md for package usage and development.
- Usage - commands, diff sources, pager, difftool, and GitHub reviews.
- Configuration - config paths, syntax settings, colors, diff rendering, and keybindings.
- Development - setup, checks, release flow, and local Pi package work.
- Contributing - repository standard and PR expectations.
Use the Nix shell when available:
nix develop
just checkWithout Nix, install the Rust toolchain from rust-toolchain.toml and run:
cargo fetch --locked
cargo build -p mark-cli --locked
cargo fmt --all --check
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-targets --all-features --lockedcrates/mark-cli command parsing, update, and CLI UX
crates/mark-command command facade shared by CLI and future integrations
crates/mark-core shared errors and path helpers
crates/mark-git low-level Git process boundary
crates/mark-diff diff loading, parsing, and plain rendering
crates/mark-syntax thin Mark settings/rendering adapter over syntaxmate
crates/mark-tui ratatui/crossterm diff review UI
crates/mark-bench local benchmark fixture generation
pi-mark Pi extension package published to npm
MIT. See LICENSE.
