A cross-platform Git diff viewer and Codex orchestrator with a Rust core and a Qt Quick/QML desktop UI.
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
- Changed-file list for diff navigation
- 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
- Embedded terminal and Chromium browser surfaces
- Light/Dark mode toggle
- Refresh action
anyhow-based error handlingtracing+tracing-subscriberlogging
crates/hunk-terminal: terminal integration, shell/session support, and terminal-facing workspace surfacescrates/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-domain: shared config/state types, SQLite-backed comment storage, markdown, and other app domain logiccrates/hunk-git: Git backend for repo discovery, diffing, branches, commits, push, publish, and synccrates/hunk-forge: forge integration logic for GitHub and related remote/review workflowscrates/hunk-updater: app update/download/install logiccrates/hunk-browser: embedded browser runtime state, CEF backend integration, offscreen frames, input routing, snapshots, console logs, and safety checkscrates/hunk-browser-helper: CEF subprocess helper binary used by the embedded browser runtimecrates/hunk-sleep-inhibitor: cross-platform idle sleep prevention for long-running AI turnscrates/hunk-desktop: Qt desktop app, QtBridge models, QML UI, and native Qt rendering adapterscrates/hunk-codex: embedded Codex app-server integration, thread service, AI reducers, and protocol boundary
- Rust 1.98
- Qt 6.11.2
- macOS, Windows, or Linux development tools for the target platform
Preferred local entry points:
just start-macjust start-linuxjust start-windowsThose helpers apply the macOS SDK wrapper when needed and stage the bundled Windows Codex runtime automatically where required.
If you want the raw macOS Cargo command, enter the pinned development shell:
nix develop -c 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 Diff 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, use the pinned Nix shell:
nix develop -c cargo build --workspace
nix develop -c cargo test --workspace
nix develop -c cargo clippy --workspace --all-targets -- -D warningsOn Linux and Windows, run the same Cargo commands directly or use the just recipes so Cargo writes to its default target/ directory.
Example:
cargo test --workspacecargo install cargo-packager
just bundle
open ./target/packager/Hunk.appCross-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_zed_like.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.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 official Codex GitHub release for the version locked in Cargo.lock:
- 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 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/tarball/DEB/RPM artifacts and publishes them to a GitHub Release when you push av*tag.
Diff previews and markdown fenced-code highlighting 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 diff projection and scrolling/render performance.
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 --forceHunk reads config from ~/.hunkdiff/config.toml.
Keyboard shortcuts are configured in the [keyboard_shortcuts] table:
[keyboard_shortcuts]
open_project = ["cmd-shift-o", "ctrl-shift-o"]
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