Lighter than the rest. A lightweight, fast Git GUI desktop application built with Tauri v2.
Twig is a GitKraken-inspired Git GUI that prioritizes speed and native Linux Wayland support. It uses a hybrid git backend: git2 (Rust) for all read operations and the system git CLI for all write operations and LFS, giving you both performance and full compatibility.
- Multi-repo tabs -- open multiple repositories in tabs with independent state
- Visual commit graph -- branching graph with colored lanes, Gravatar avatars, virtualized scrolling (handles 10k+ commits)
- Branch management -- local/remote branch listing, checkout, create, rename, delete, push, fetch
- Diff viewer -- unified and split views, syntax-colored additions/deletions, LFS pointer detection, binary file handling
- Staging area -- unstaged/staged file lists, per-file or bulk stage/unstage, inline diff preview
- Commit & sync -- commit message editor (Ctrl+Enter), push, pull
| Layer | Technology |
|---|---|
| Framework | Tauri v2 (Rust + WebView) |
| Frontend | Svelte 5, TypeScript, Vite |
| Styling | TailwindCSS v4 (dark theme) |
| Git reads | git2 Rust crate |
| Git writes | System git CLI via tokio::process |
| Icons | Lucide Svelte |
Primary: Linux (Wayland via WebKitGTK). Also works on X11, macOS, and Windows.
NVIDIA + Wayland is handled automatically at runtime (GPU detection in main.rs).
- Rust >= 1.77 (with
cargo) - Node.js >= 20 (with
npm) - System dependencies (Linux):
libwebkit2gtk-4.1-dev,libgtk-3-dev,libappindicator3-dev,librsvg2-dev,libssl-dev
On Arch/CachyOS:
sudo pacman -S webkit2gtk-4.1 gtk3 libappindicator-gtk3On Ubuntu/Debian:
sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libappindicator3-dev librsvg2-dev libssl-devnpm install
npm run tauri devThis starts the Vite dev server with HMR and launches the Tauri app. Rust recompiles on changes to src-tauri/.
npm run tauri buildOutputs a release binary and platform packages (.deb, .rpm, .AppImage) in src-tauri/target/release/bundle/.
twig/
├── src-tauri/ # Rust backend (Tauri)
│ ├── src/
│ │ ├── main.rs # Entry point, Wayland GPU setup
│ │ ├── lib.rs # Tauri builder, command registration
│ │ ├── state.rs # AppState: thread-safe open repo map
│ │ ├── error.rs # TwigError enum (thiserror)
│ │ ├── commands/ # Tauri command handlers
│ │ │ ├── repo.rs # Open, close, list repos
│ │ │ ├── graph.rs # Commit graph data
│ │ │ ├── branches.rs # Branch CRUD + push/fetch
│ │ │ ├── diff.rs # Commit and working diffs
│ │ │ └── staging.rs # Stage/unstage, commit, pull
│ │ └── git/ # Git operations layer
│ │ ├── reader.rs # git2-based reads (graph, branches, diffs)
│ │ └── writer.rs # CLI-based writes (checkout, push, commit)
│ ├── Cargo.toml
│ └── tauri.conf.json
├── src/ # Svelte frontend
│ ├── main.ts # App mount
│ ├── App.svelte # Root component
│ ├── app.css # TailwindCSS v4 + design system tokens
│ ├── lib/
│ │ ├── tauri.ts # Typed invoke() wrappers
│ │ ├── types/git.ts # TypeScript interfaces
│ │ └── stores/ # Svelte stores (repos, graph, ui)
│ └── components/
│ ├── layout/ # AppShell, TabBar, Sidebar
│ ├── graph/ # CommitGraph, GraphCanvas, CommitRow
│ ├── branches/ # BranchList
│ ├── diff/ # DiffViewer, DiffHunk
│ └── staging/ # StagingArea
├── index.html
├── package.json
├── vite.config.ts
└── tsconfig.json
All git operations happen in Rust. The frontend only calls Tauri commands and renders state.
Frontend (Svelte) ──invoke()──> Commands (Tauri) ──> Git Layer (git2 / CLI)
│ │
└── Stores ◄── State updates ◄── Results ◄───────────────┘
| Operation | Backend | Rationale |
|---|---|---|
| Commit graph, branches, diffs, status | git2 |
Fast, in-process, no subprocess overhead |
| Checkout, commit, push, pull, fetch, stage | System git CLI |
Full compatibility, hooks, LFS, credential helpers |
The graph uses a lane assignment algorithm that:
- Walks commits in topological order
- Assigns each commit to a lane (column), reusing free lanes
- First parent inherits the lane (straight continuation), merge parents branch off
- Outputs per-row data: commit lane, pass-through rails, parent lane targets
The frontend renders each row as an SVG with vertical rails, bezier curves for merges, and colored commit nodes. Rows are virtualized (only ~50 visible at a time) for performance with large repos.
Dark theme only. Key tokens defined in app.css via @theme:
| Token | Value | Usage |
|---|---|---|
--color-bg |
#1a1b26 |
Main background |
--color-surface |
#1f2335 |
Panels, sidebar |
--color-surface-elevated |
#24283b |
Hover states, active items |
--color-accent |
#7aa2f7 |
Primary accent (blue) |
--color-accent-secondary |
#bb9af7 |
Tags, special branches (purple) |
--color-lane-0..5 |
Various | Git graph lane colors |
See CONTRIBUTING.md for guidelines.
AGPL-3.0 - Copyright 2026 Igor Kalicinski
