A code review TUI with vim keybindings. Export to GitHub, GitLab, Bitbucket, or clipboard.
Tip
Pronounced "tweaker".
- GitHub-style continuous diff in the terminal. Scroll through every changed file in one stream.
- PR-style comments at the line, range, file, and review level.
- Review tracking at file or hunk granularity, persisted across sessions.
- Three export targets: push a real review to GitHub, GitLab, or Bitbucket, copy structured markdown to your clipboard, or pipe to stdout.
- Works with git, jj, and mercurial. Reviews uncommitted changes, commit ranges, or any GitHub PR, GitLab MR, or Bitbucket PR.
curl -fsSL tuicr.dev/install.sh | sh # or brew install tuicr # or sudo pacman -S tuicr
Other install methods (cargo, mise, nix, binaries, source)
# Cargo cargo install tuicr # Mise mise use github:agavra/tuicr # Nix nix run github:agavra/tuicr
Pre-built binaries: GitHub Releases. Linux releases include dynamically linked GNU and static musl variants.
From source:
git clone https://github.com/agavra/tuicr.git cd tuicr cargo install --path .
Update the active installation with one command:
tuicr update
tuicr update 0.18.0 # Install a known-good versiontuicr update uses Homebrew, Cargo, Mise, or a Nix profile when that manager owns the
executable. Install-script and manually downloaded binaries update in place from the matching
GitHub release asset after SHA-256 verification. Exact-version installs support Cargo and direct
binaries; use the package manager's pinning workflow for Homebrew, Mise, or Nix. A nix run
invocation is temporary rather than installed; rerun it to use the current flake, or use
nix profile install github:agavra/tuicr for an installation that tuicr update can upgrade.
tuicr # Pick from a commit selector tuicr tui # Same TUI, explicit subcommand tuicr -w # Uncommitted changes (skip selector) tuicr -r main..HEAD # Commit range tuicr pr 125 # GitHub PR, or Bitbucket PR tuicr mr 125 # GitLab MR tuicr tui pr 125 # GitHub PR via explicit TUI subcommand tuicr tui mr 125 # GitLab MR via explicit TUI subcommand tuicr --stdout # Pipe the review to stdout tuicr review list # List saved local review sessions tuicr update # Update the active installation tuicr update 0.18.0 # Install a known-good version
Inside tuicr, navigate with j/k, press c to comment, then y to copy the review or
:submit to push it to GitHub, GitLab, or Bitbucket. When reopening a pull request you've reviewed
before, tuicr preselects commits newer than your latest submitted review when that metadata is
available; commits already covered by that review are marked with ✓ in the inline selector.
(Bitbucket does not record which commit an approval covered, so that preselection does not apply
there.)
Use :summary during a review to show every pending local-draft comment. The summary replaces the
diff while leaving the file sidebar visible when it is open. The first
comment is selected when the view opens; use j/k to select the next or previous comment, and
the view scrolls automatically to keep it visible. Press Enter to jump to the selected comment
in the continuous diff, leaving single-file view if necessary, or Esc to return to the diff. If
its file or hunk is already marked reviewed, tuicr reveals the target without clearing that
reviewed state.
Auto-detects git, jj, or mercurial.
| tuicr | hunk | lumen | gh pr review |
git diff |
|
|---|---|---|---|---|---|
| TUI diff viewer | ✅ | ✅ | ✅ | ❌ | ❌ |
| Write comments in the TUI | ✅ | ✅ | ✅ | ❌ | ❌ |
| Vim keybindings | ✅ | ❌ | partial1 | ❌ | ❌ |
| Push inline review to GitHub | ✅ | ❌ | ❌ | partial2 | ❌ |
| Push inline review to GitLab | ✅ | ❌ | ❌ | ❌ | ❌ |
| Push inline review to Bitbucket | ✅ | ❌ | ❌ | ❌ | ❌ |
| Agent-ready markdown export | ✅ | via CLI skill | ❌ | ❌ | ❌ |
| git | ✅ | ✅ | ✅ | ❌ | ✅ |
| jj | ✅ | ✅ | ✅ | ❌ | ❌ |
| Mercurial (hg) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Single static binary | ✅ | ✅ | ✅ | ✅ | ✅ |
1 Lumen has j/k navigation but no broader vim model (visual mode, {N}G, Ctrl-d/Ctrl-u,
etc.).
2 gh pr review posts approve/comment/request-changes at the review level only. No inline line
comments.
When you're done reviewing, send your comments wherever the work continues.
:submit opens a picker for Comment, Approve, Request changes, or Draft. Inline comments land
on the right lines as a real PR review. Review-level comments become the review summary.
Requires gh authenticated to the repo.
:submit offers Comment, Approve, or Request changes on a GitLab MR. Inline comments post as
discussion notes. Review-level comments become the summary. Requires glab authenticated to the
host. Request changes needs your account to be an assigned reviewer. Only Draft is GitHub-only
here. See docs/GITLAB.md for setup, self-hosted instances, and troubleshooting.
:submit offers Comment or Approve on a Bitbucket Cloud PR. Inline comments post as inline PR
comments, multi-line ranges included; review-level comments become general PR comments. Requires
bkt authenticated to bitbucket.org. Request changes and Draft are not supported yet, and
Bitbucket Data Center is out of scope. See docs/BITBUCKET.md for setup,
required token scopes, and troubleshooting.
:submit offers Comment, Approve, or Request changes on an Azure DevOps PR. Inline comments post
as PR comment threads; Approve/Request changes also cast a reviewer vote. Auth is a Personal
Access Token in AZURE_DEVOPS_EXT_PAT (preferred — works with enterprise tenants), falling back
to az login via the Azure CLI. Run tuicr from a local clone of the repo — Azure exposes no
unified-diff API, so the diff is built with git diff base...head. See
docs/AZURE.md for setup, supported URL forms, and MVP limitations.
y or :clip copies a structured markdown block to your clipboard. Each comment has a number
and a file/line anchor:
I reviewed your code and have the following comments. Please address them. 1. `src/auth.rs` - Consider adding unit tests 2. `src/auth.rs:42` - Magic number should be a named constant 3. `src/auth.rs:50-55` - This block could be refactored
Paste it back to any coding agent (Claude, Codex, Cursor, etc).
For an agent-driven workflow where your agent opens tuicr in a cmux, tmux, Zellij, or Herdr split pane, see skills/tuicr/SKILL.md.
Run with --stdout to pipe the markdown to another process:
tuicr --stdout > review.md tuicr --stdout | pbcopy
tuicr review exposes saved sessions without opening the TUI. It can list
sessions, add comments, and print stored comments for agent and script
integrations. See docs/REVIEW_CLI.md.
The TUI creates a persisted session file when a review target becomes active,
so collaborative tools can add comments immediately. Empty auto-created session
files are removed when the TUI exits. tuicr review list marks currently open
TUI sessions with "active": true.
Inside the TUI, the review target selector's Sessions tab lists the saved
reviews for the current checkout, so you can resume one by picking it instead of
retyping the commit range it was opened with. Open it with :sessions or cycle
to it with Tab.
tuicr also exposes a Rust library API for tools that want to build on top of its
persisted review sessions. ReviewStore can list sessions for a checkout, load a
session, and add review, file, line, or range comments using the same insertion
primitive as the TUI.
use tuicr::{AddCommentRequest, CommentTarget, CommentType, LineSide, ReviewStore}; let store = ReviewStore::new(); let sessions = store.list_sessions_for_repo("/path/to/repo")?; let session = &sessions[0].session_ref; store.add_comment( session, AddCommentRequest { target: CommentTarget::Line { path: "src/main.rs".into(), line: 42, side: LineSide::New, }, content: "Handle the empty case here.".into(), comment_type: CommentType::from_id("issue"), }, )?;
Path: ~/.config/tuicr/config.toml on Linux/macOS, %APPDATA%\tuicr\config.toml on Windows.
theme = "catppuccin-mocha" diff_view = "side-by-side" # or "unified" ignore_whitespace = false # ignore all whitespace in local VCS diffs appearance = "system" # or "dark" / "light" mouse = true leader = ";" # configurable prefix for leader shortcuts editor = "nvim" # editor for `e` / `:edit`; overrides $EDITOR comment_vim = false # vim modal editing in the review comment box relative_line_numbers = false # show rendered-row distances in the diff gutter [[comment_types]] id = "issue" color = "red" definition = "must fix before merge"
Bundled themes: dark, light, ayu-light, ayu-mirage, onedark, github-light,
github-dark, catppuccin-latte, catppuccin-frappe, catppuccin-macchiato,
catppuccin-mocha, everforest-dark, everforest-light, gruvbox-dark,
gruvbox-light, nord-dark, nord-light, nord-dark-high-contrast,
nord-light-high-contrast, solarized-light, solarized-dark, tokyo-night-storm,
tokyo-night-day.
Local themes: set theme = "my-theme" or run tuicr --theme my-theme, then create
~/.config/tuicr/themes/my-theme.toml on Linux/macOS or %APPDATA%\tuicr\themes\my-theme.toml
on Windows. Local themes may reference a local syntax_theme = "my-syntax.tmTheme" file for
syntax highlighting. A ready-to-copy example lives at examples/tuicr-teal.toml
with its matching examples/tuicr-teal-syntax.tmTheme syntax theme.
Full options, theme resolution precedence, comment_types semantics, and .tuicrignore rules in
docs/CONFIG.md.
A first-session cheatsheet. Press ? inside tuicr for the full reference.
| Key | Action |
|---|---|
j / k |
Down / up |
Ctrl-d / Ctrl-u |
Half-page down / up |
g / G |
Top / bottom |
{ / } |
Previous / next file |
[ / ] |
Previous / next hunk |
m / M |
Next / previous comment |
/ |
Search the diff, the file tree, or help — whichever is focused/open (case-insensitive) |
n / N |
Next / previous search match (wraps); matches stay highlighted — Esc clears |
i / e (file tree) |
Filter files in / out by regex; narrows the tree and the diff |
I / E (file tree) |
Clear the include / exclude filter |
c / C |
Add line / file comment |
v / V |
Visual mode (range comment) |
r |
Toggle file reviewed |
R |
Toggle hunk reviewed |
e |
Open focused file in $EDITOR |
y |
Copy review to clipboard |
:edit |
Open focused file in $EDITOR |
:submit |
Push review to GitHub, GitLab, or Bitbucket |
Tab in : prompt |
Complete or cycle commands |
? |
Toggle full help |
Full reference in docs/KEYBINDINGS.md.
Thanks to the folks below for keeping tuicr development going, it means a lot to have the work I'm doing here appreciated!
MIT licensed. Contribution notes in CONTRIBUTING.md.