dlvhdr/diffnav
{ "createdAt": "2024-09-18T14:41:16Z", "defaultBranch": "main", "description": "A git diff pager based on delta but with a file tree, à la GitHub.", "fullName": "dlvhdr/diffnav", "homepage": "", "language": "Go", "name": "diffnav", "pushedAt": "2026-03-21T14:24:51Z", "stargazersCount": 1160, "topics": [ "cli", "delta", "diff", "git", "github", "golang", "tui" ], "updatedAt": "2026-03-21T21:15:58Z", "url": "https://github.com/dlvhdr/diffnav"}
A git diff pager based on delta but with a file tree, à la GitHub.
Donating ❤️
Section titled “Donating ❤️”If you enjoy diffnav and want to help, consider supporting the project with a
donation at the sponsors page.
Installation
Section titled “Installation”Homebrew:
brew install dlvhdr/formulae/diffnavGo:
git clone https://github.com/dlvhdr/diffnav.gitcd diffnavgo install .[!NOTE] To get the icons to render properly you should download and install a Nerd font from https://www.nerdfonts.com/. Then, select that font as your font for the terminal.
You can install these with brew as well:
brew install --cask font-<FONT NAME>-nerd-font
Pipe into diffnav
Section titled “Pipe into diffnav”git diff | diffnavgh pr diff https://github.com/dlvhdr/gh-dash/pull/447 | diffnav
Set up as Global Git Diff Pager
Section titled “Set up as Global Git Diff Pager”git config --global pager.diff diffnav| Flag | Description |
|---|---|
--side-by-side, -s | Force side-by-side diff view |
--unified, -u | Force unified diff view |
--watch, -w | Watch mode: periodically re-run a command and refresh |
--watch-cmd | Command to run in watch mode (implies --watch, default: git diff) |
--watch-interval | Interval between watch refreshes (default: 2s) |
Example:
git diff | diffnav --unifiedgit diff | diffnav -uWatch Mode
Section titled “Watch Mode”Watch mode lets diffnav periodically re-run a diff command and refresh the display automatically. This is useful for monitoring changes as you work.
# watch unstaged changes (default: git diff, every 2s)diffnav --watch
# watch staged changes with a custom intervaldiffnav --watch-cmd "git diff --cached" --watch-interval 5s
# watch changes against a specific branchdiffnav --watch-cmd "git diff main..."Configuration
Section titled “Configuration”The config file is searched in this order:
$DIFFNAV_CONFIG_DIR/config.yml(if env var is set)$XDG_CONFIG_HOME/diffnav/config.yml(if set, macOS only)~/.config/diffnav/config.yml(macOS and Linux)- OS-specific config directory (e.g.,
~/Library/Application Support/diffnav/config.ymlon macOS)
Example config file:
ui: # Hide the header to get more screen space for diffs hideHeader: true
# Hide the footer (keybindings help) hideFooter: true
# Start with the file tree hidden (toggle with 'e') showFileTree: false
# Customize the file tree width (default: 26) fileTreeWidth: 30
# Customize the search panel width (default: 50) searchTreeWidth: 60
# Icon style: "status" (default), "simple", "filetype", "full", "unicode", or "ascii" icons: nerd-fonts-status
# Color filenames by git status (default: true) colorFileNames: false
# Show the amount of lines added / removed next to the file showDiffStats: false
# Use side-by-side diff view (default: true, set false for unified) sideBySide: true| Option | Type | Default | Description |
|---|---|---|---|
ui.hideHeader | bool | false | Hide the “DIFFNAV” header |
ui.hideFooter | bool | false | Hide the footer with keybindings help |
ui.showFileTree | bool | true | Show file tree on startup |
ui.fileTreeWidth | int | 26 | Width of the file tree sidebar |
ui.searchTreeWidth | int | 50 | Width of the search panel |
ui.icons | string | nerd-fonts-status | Icon style (see below for details) |
ui.colorFileNames | bool | true | Color filenames by git status |
ui.showDiffStats | bool | true | Show the amount of lines added / removed next to the file |
ui.sideBySide | bool | true | Use side-by-side diff view (false for unified) |
Icon Styles
Section titled “Icon Styles”| Style | Description |
|---|---|
nerd-fonts-status | Boxed git status icons colored by change type |
nerd-fonts-simple | Generic file icon colored by change type |
nerd-fonts-filetype | File-type specific icons (language icons) colored by change type |
nerd-fonts-full | Both status icon and file-type icon, all colored |
unicode | Unicode symbols (+/⛌/●) |
ascii | Plain ASCII characters (+/x/*) |
You can also configure the diff rendering through delta. Check out their docs.
If you want the exact delta configuration I’m using - it can be found here.
| Key | Description |
|---|---|
| j | Next node |
| k | Previous node |
| n | Next file |
| p / N | Previous file |
| Ctrl-d | Scroll the diff down |
| Ctrl-u | Scroll the diff up |
| e | Toggle the file tree |
| t | Search/go-to file |
| y | Copy file path |
| i | Cycle icon style |
| o | Open file in $EDITOR |
| s | Toggle side-by-side/unified view |
| Tab | Switch focus between the panes |
| q | Quit |
Discord
Section titled “Discord”Have questions? Join our Discord community!
Contributing
Section titled “Contributing”See the contribution guide at https://www.gh-dash.dev/contributing.
Under the Hood
Section titled “Under the Hood”diffnav uses:
- Bubble Tea for the TUI
deltafor viewing the diffed file
Screenshots use:
- kitty for the terminal
- tokyonight for the color scheme
- CommitMono for the font