A cross-platform Git diff viewer and Codex orchestrator built with gpui + gpui-component.
Hunk is licensed under the GNU General Public License v3.0 or later. See LICENSE.
Nobody writes code anymore, people just review code. So we need the best diff viewer possible so that vibe engineers can review code and tell AI what to fix. Hunk is also has full codex integration so you can use Codex inside of Hunk instead of codex-cli or any other desktop app.
- Uses a native Git backend built on
gixwith narrowgit2fallbacks for unsupported write flows - Managed Git worktrees with per-worktree branch publishing
- File tree for changed files
- Side-by-side diff viewer with per-line styling and line numbers
- Review compare mode for
base branch <-> workspace targetand custom branch/worktree pairs - AI drafts and threads scoped to the selected project checkout or worktree
- Resizable split panes (tree + diff)
- Light/Dark mode toggle
- Refresh action
anyhow-based error handlingtracing+tracing-subscriberlogging
crates/hunk-domain: config/state/db/diff/markdown domain logiccrates/hunk-git: Git backend for repo discovery, diffing, branches, commits, push, and synccrates/hunk-text: rope-backed text model, positions/ranges, transactions, and undo/redo primitivescrates/hunk-language: Tree-sitter language registry, syntax highlighting, preview highlighting, folds, and language-intelligence seamscrates/hunk-editor: headless editor state, selections, display rows, folds, overlays, and editor commandscrates/hunk-desktop: GPUI desktop app binarycrates/hunk-codex: Codex Websocket Server handling logic
- macOS
- Xcode + command line tools
- Metal toolchain for GPUI shader compilation
Preferred local entry points:
just start-macjust start-linuxjust start-windowsThose helpers resolve CARGO_TARGET_DIR correctly, apply the macOS SDK wrapper when needed, and stage the bundled Windows Codex runtime automatically.
If you want the raw macOS cargo command, use:
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" \
./scripts/run_with_macos_sdk_env.sh cargo run -p hunk-desktopLaunch from anywhere, then use File > Open Project... (or Cmd/Ctrl+Shift+O) to choose a Git repository.
The app still launches from Terminal in local dev, so macOS may present it like a terminal-launched app.
Hunk treats the primary checkout and each linked Git worktree as separate workspace targets.
- Create and switch worktrees from the Git tab.
- Managed worktrees live under
~/.hunkdiff/worktrees/<repo-key>/worktree-N. - The Files and Git tabs follow the currently active workspace target.
- The Review tab defaults to comparing the active workspace target against the repo base branch, but you can also compare custom branch/worktree pairs.
- The AI tab can start a new thread in the primary checkout with
Cmd/Ctrl+Nor in a worktree-targeted draft withCmd/Ctrl+Shift+N.
On macOS:
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" \
./scripts/run_with_macos_sdk_env.sh cargo build --workspace
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" \
./scripts/run_with_macos_sdk_env.sh cargo test --workspace
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" \
./scripts/run_with_macos_sdk_env.sh cargo clippy --workspace --all-targets -- -D warningsOn Linux and Windows, run the same Cargo commands with CARGO_TARGET_DIR resolved through scripts/resolve_cargo_target_dir.sh or the just recipes so builds land in target-shared.
Example:
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" cargo test --workspacecargo install cargo-packager
just bundle
open "$(./scripts/resolve_cargo_target_dir.sh)/packager/Hunk.app"Cross-platform binary build helpers:
./scripts/build_linux.sh
./scripts/build_windows.shOptional flags:
--target <triple>to override the default target triple (must match the script platform).--debugto build debug artifacts.--no-stage-runtimeto skip copying the bundled Codex runtime into the target output tree.
Release packaging helpers:
./scripts/package_macos_release.sh
./scripts/package_linux_release.sh
pwsh ./scripts/package_windows_release.ps1These produce:
- macOS ARM64:
Hunk-<version>-macos-arm64.dmg, signed/notarized when Apple secrets are configured - Linux x86_64:
Hunk-<version>-linux-x86_64.AppImage, fallbackHunk-<version>-linux-x86_64.tar.gz,hunk-desktop_<version>-1_amd64.deb, andhunk-desktop-<rpm-version>-1.x86_64.rpm - Windows x86_64:
Hunk-<version>-windows-x86_64.msi
Linux release packaging is custom and does not use cargo packager. On Ubuntu hosts you can either enter nix develop to get the packaging toolchain from the flake, or install host deps with just install-linux-packaging-deps-ubuntu, then use:
just package-linux-release
just package-linux-deb-release
just package-linux-rpm-release
just smoke-test-linux-deb
just smoke-test-linux-rpmThe Debian smoke test installs the package in an Ubuntu container. The RPM smoke test installs it in a Fedora container.
Hunk embeds a native codex runtime and launches app-server mode with:
codex app-server --listen ws://127.0.0.1:<port>.
Expected embedded runtime paths:
assets/codex-runtime/macos/codexassets/codex-runtime/linux/codexassets/codex-runtime/windows/codex.cmdassets/codex-runtime/windows/codex.exe
Runtime layout details also live in assets/codex-runtime/README.md.
The pinned Codex baseline is tracked in docs/AI_CODEX_SPEC.md.
./scripts/download_codex_runtime_unix.sh macosPlatform-specific download helpers:
- macOS ARM64:
./scripts/download_codex_runtime_unix.sh macos - Linux x86_64:
./scripts/download_codex_runtime_unix.sh linux - Windows x86_64:
pwsh ./scripts/download_codex_runtime_windows.ps1
The Windows helper stages both assets/codex-runtime/windows/codex.exe and the bundled launcher assets/codex-runtime/windows/codex.cmd.
These pull the pinned release assets directly from the Codex GitHub release for the tag in crates/hunk-desktop/Cargo.toml:
- macOS ARM64:
codex-aarch64-apple-darwin.tar.gz - Linux x86_64:
codex-x86_64-unknown-linux-musl.tar.gz - Windows x86_64:
codex-x86_64-pc-windows-msvc.exe.zip
If you already have a local native binary you want to use for macOS instead, you can still override the source path:
./scripts/install_codex_runtime_macos.sh /absolute/path/to/codex
Download and stage the pinned macOS runtime:
./scripts/install_codex_runtime_macos.sh
./scripts/validate_codex_runtime_bundle.sh --strict --platform macos
./scripts/stage_codex_runtime_macos.sh
CARGO_TARGET_DIR="$(./scripts/resolve_cargo_target_dir.sh)" \
./scripts/run_with_macos_sdk_env.sh cargo test -p hunk-codex --test real_runtime_smoke -- --ignored
just bundle.github/workflows/pr-build.ymlstays as the main PR CI workflow..github/workflows/release.ymlbuilds DMG/MSI/AppImage/DEB/RPM artifacts and publishes them to a GitHub Release when you push av*tag.
The release workflows no longer bundle the old Helix runtime. The editor now uses the curated Tree-sitter language set compiled into hunk-language.
The Files editor, file preview, and markdown fenced-code highlighting now use the shared Tree-sitter language registry in crates/hunk-language.
Built-in languages/config formats:
- Rust
- JavaScript
- TypeScript
- TSX
- Bash / shell
- Python
- PowerShell
- JSON
- YAML
- Go
- HTML
- CSS
- TOML
- Java
- Kotlin
- C
- C++
- C#
- SQL
- Markdown
- Dockerfile
- Nix
- Terraform / HCL
- Swift
Apple signing/notarization secrets used by the workflows:
APPLE_CERTIFICATE_P12_BASE64APPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYAPPLE_NOTARY_API_KEY_BASE64APPLE_NOTARY_KEY_IDAPPLE_NOTARY_ISSUER
Windows signing is not configured in this repo yet. The current release workflow produces an unsigned MSI until you add a paid Windows signing solution.
Generate a synthetic Git repository with a very large working-copy diff:
./scripts/create_large_diff_repo.sh --lines 25000 --files 1 --forceThe script prints the generated repo path and total diff size. Open that folder in Hunk to stress scrolling/render performance and watch the FPS badge in the toolbar.
Generate code-like diffs instead of plain text (txt, js, or ts):
./scripts/create_large_diff_repo.sh --lines 25000 --files 20 --lang ts --force
./scripts/create_large_diff_repo.sh --lines 25000 --files 20 --lang js --forceTo spread the same total load across multiple files:
./scripts/create_large_diff_repo.sh --lines 6000 --files 4 --forceRun the repeatable large-diff perf harness with threshold gating:
./scripts/run_perf_harness.shRun without threshold gating (metrics only):
./scripts/run_perf_harness.sh --no-gateProtocol and metric definitions are documented in PERFORMANCE_BENCHMARK.md.
The harness script currently targets Unix-like shells (bash).
Hunk reads config from ~/.hunkdiff/config.toml.
Keyboard shortcuts are configured in the [keyboard_shortcuts] table:
[keyboard_shortcuts]
toggle_sidebar_tree = ["cmd-b", "ctrl-b"]
open_project = ["cmd-shift-o", "ctrl-shift-o"]
save_current_file = ["cmd-s", "ctrl-s"]
open_settings = ["cmd-,", "ctrl-,"]
quit_app = ["cmd-q"]Use an empty list to disable a shortcut action:
[keyboard_shortcuts]
quit_app = []Generate git-diff icon variants and rebuild the bundle:
./scripts/generate_diff_icons.py
./scripts/build_macos_icon.sh
./scripts/build_windows_icon.sh
just bundleGenerated assets:
assets/icons/hunk-icon-default.png(default/full color)assets/icons/hunk-icon-dark.png(dark appearance variant)assets/icons/hunk-icon-mono.png(monochrome/tint-friendly variant)
Current packaging uses Hunk.icns, Hunk.ico, and hunk_new.png through cargo-packager.
Install bacon once:
cargo install baconStart hot reload (default job is run):
baconUseful jobs:
bacon check
bacon test
bacon clippyKeybindings in bacon UI:
r-> runc-> checkt-> testl-> clippy