jj-diff

A fast, keyboard-driven TUI for viewing and manipulating diffs in Jujutsu (jj). Move changes between commits, split commits interactively, or use as a drop-in replacement for jj's builtin diff editor.
Features
- Browse Mode: View diffs with syntax highlighting, search, and fuzzy file finding
- Interactive Mode: Select and move hunks or individual lines between revisions
- Diff-Editor Mode: Use with
jj split, jj diffedit, jj amend -i, jj squash -i
- Multi-Split Mode: Tag changes and split commits into multiple focused commits
- Fast: Handles 5000+ files and 20K+ line diffs instantly
- Beautiful: Catppuccin themes with syntax highlighting for 100+ languages
Installation
# Build from source
mise install && hk install --mise
mise run build
# Or install with go
go install github.com/kyleking/jj-diff/cmd/jj-diff@latest
Quick Start
Browse Diffs
View and search through changes:
# View working copy changes
jj-diff
# View specific revision
jj-diff -r @-
# Search with '/', fuzzy find with 'f'
Move Changes Between Commits
Interactively select hunks or lines to move:
jj-diff --interactive
# Press 'd' to select destination
# Press Space to select hunks
# Press 'v' for line-level selection
# Press 'a' to apply changes
Use as jj's Diff-Editor
Replace jj's builtin editor:
# ~/.config/jj/config.toml
[ui]
diff-editor = "jj-diff"
diff-instructions = false
Then use with jj commands:
jj split # Split current commit
jj diffedit # Edit changes in commit
jj amend -i # Amend interactively
jj squash -i # Squash interactively
Split Commits into Multiple Parts
Tag changes and create focused commits:
jj-diff --interactive
# Press 'S' to enter multi-split mode
# Tag hunks with 'a', 'b', 'c', etc.
# Press 'D' to assign tags to commits
# Press 'P' to preview and apply
Keybindings
Press ? for help overlay with all keybindings.
Essential Keys
| Key |
Action |
j/k or ↓/↑ |
Navigate files or scroll diff |
Tab |
Switch focus between file list and diff |
n/p |
Next/previous hunk |
/ |
Search files and content |
f |
Filter files (type to search) |
? |
Show help |
q |
Quit |
Interactive Mode
| Key |
Action |
d |
Select destination revision |
Space |
Toggle hunk selection |
v |
Enter visual mode (line selection) |
a |
Apply selected changes |
S |
Toggle multi-split mode |
Multi-Split Mode
| Key |
Action |
a-z |
Tag hunk with letter |
D |
Assign tags to commits |
P |
Preview and apply split |
Visual Indicators
> Current hunk/line
[X] Selected hunk
[A] Tagged hunk (multi-split)
█ Visual selection range
• Selected line
Common Workflows
Move a Few Lines to Previous Commit
jj-diff --interactive
# Press 'd', select @-, press Enter
# Navigate to desired hunk with 'n'
# Press 'v' to enter visual mode
# Select lines with 'j/k'
# Press Space to confirm selection
# Press 'a' to apply
Split a Large Commit into Focused Changes
jj-diff --interactive
# Press 'S' to enter multi-split mode
# Tag related changes: press 'a' on UI changes, 'b' on tests, etc.
# Press 'D' to open assignment modal
# Assign tags to existing commits or create new ones
# Press 'P' to preview and apply split
Review Changes Before Committing
# Browse mode (read-only)
jj-diff
# Use '/' to search for TODO comments
# Use 'f' to quickly jump between files
# Press Tab to focus diff and scroll with j/k
Edit a Commit Interactively
# Configure jj-diff as diff-editor first
jj diffedit -r @-
# Select changes to keep with Space
# Line-level editing with 'v'
# Press 'a' to save and exit
jj-diff is optimized for real-world use:
- Handles 5,000+ files instantly (7μs render time)
- 20,000+ line diffs with no lag (52μs render time)
- Search across 100K lines in 17ms
- Syntax highlighting for 100+ languages
Tested on large repositories with excellent responsiveness.
Contributing
See CONTRIBUTING.md for development setup, tasks, and the git workflow, and DESIGN.md for the architecture overview, patterns, and testing guide.
Troubleshooting
TUI rendering issues: Try setting TERM=xterm-256color
Performance issues: Disable syntax highlighting or use browse mode for very large diffs
jj integration fails: Ensure jj 0.9.0+ is installed and in PATH
License
MIT