Guide

Everything you need after the download, in the order you'll need it. Paths, commands and limits here are the real ones, taken from the code — including the places where the app is stricter or quieter than you'd expect.

1 · Install and first launch

Three installers, published on every tagged release. Pick yours from the latest release.

PlatformBuildNeeds
macOSApple Silicon · .dmgNothing — WKWebView ships with the OS
Linuxx64 · .AppImagelibwebkit2gtk-4.1
Windowsx64 · .exeWebView2 Runtime (already on Windows 11)

There is no Intel Mac build, and no .deb, .rpm or .msi. Both gh and glab are inside every installer, so there is nothing else to fetch.

Getting past the first-launch warning

The builds are not code-signed, so both macOS and Windows stop them once. Nothing is wrong with the download — the warning exists because there is no certificate behind it.

macOS — drag the app to /Applications, then either right-click it and choose Open, or clear the quarantine flag:

xattr -dr com.apple.quarantine /Applications/BeardGit.app

Windows — SmartScreen → More infoRun anyway. It won't ask again on that machine.

Linux — make the AppImage executable and run it:

chmod +x BeardGit-*.AppImage
./BeardGit-*.AppImage

One thing to check

BeardGit reads your repositories through libgit2, but every write — commit, push, rebase, merge — runs your own git. It needs to be on your PATH, and the app does not check at startup: if it's missing, the first commit fails instead of the app warning you. git --version in a terminal is the whole test. What BeardGit does fix by itself is the empty PATH a desktop launcher hands a GUI app, so opening it from Finder or a dock still finds your tools.

2 · Opening your first repository

The welcome screen has three ways in: open a folder, clone a URL, or pick one you had open before. Every repository is a tab, and only the active tab keeps its heavy state — the graph layout, the file watcher — so a dozen open repos cost about what one does.

  • Open a folder that isn't a repository yet and BeardGit offers to set it up in one pass: git init, drop in a .gitignore, make the first commit, create the matching repo on GitHub or GitLab, wire the remote and push. Every step is optional, and if one fails the earlier ones stay done.
  • Tabs⌘Tab and ⌘⇧Tab move between them, ⌘W closes the active one, and dragging a tab reorders it.
  • Sections remember where you left them for the length of the session: filters, scroll positions, pane widths, collapsed folders, and half-written drafts like a commit message or a review comment. Per repository tab, dropped when the tab closes, never written to disk.

External changes are picked up on their own. A commit you make in a terminal, a branch your teammate pushed, a file another program rewrote — a debounced watcher notices and the views refresh, including inside linked worktrees and submodules.

The welcome screen with buttons to open or clone a repository and a list of recent ones
the welcome screen, on a launch with no repository open

3 · Connecting GitHub or GitLab

BeardGit talks to both through gh and glab, and it drives its own bundled copies rather than whatever is on your PATH — same versions for everyone. Logging in is the CLI's normal flow:

  1. Settings → Integrations → the forge you want, then Log in. A terminal tab opens and runs auth login on the bundled binary, so it works even if you have never installed gh or glab yourself.
  2. Follow the CLI's prompts. Your credentials go where that CLI keeps them — your own config and system keyring, keyed by host — not into BeardGit.
  3. Open a repository whose origin points at that host and the forge views appear: pull or merge requests, issues, pipelines, releases, repo settings.

Self-hosted works as-is. GitHub Enterprise and on-prem GitLab are normal hosts here. Auth is checked per host, so a forge that only answers on the VPN cannot shadow one that's reachable, and a personal gitlab.com plus a corporate GitLab can be connected at the same time.

If you also store a personal access token in BeardGit, it is encrypted on your machine — see where your data lives. Turning the integration off in Settings stops the app validating those tokens at launch and resolving your remote against the forge API; nothing is deleted, and turning it back on reconnects.

4 · Setting up an AI CLI

BeardGit has no model and no API key of its own. It runs your install of Claude Code, Codex or OpenCode, which already have their own auth. Install one, make sure it works in a terminal, and BeardGit finds it: at launch it looks each of the three up on your PATH and asks for --version. Settings → AI is where you pick the preferred provider and re-run that detection.

Background runs

A background run is the interesting part. Give it a prompt and it starts on a fresh branch, ai/<provider>/<slug>, in a git worktree of its own — by default under .beardgit/ai-worktrees/, and you can point that somewhere else in Settings. Your checkout is untouched while it works. Runs are queued against a concurrency cap you set (three by default).

When it finishes you can read the transcript, look at the diff, and then merge the branch, keep the worktree for later, or discard it. The run also writes a Markdown report into .beardgit/ai-reports/ in the parent repository, so discarding the worktree doesn't take the write-up with it.

The small AI actions

From any view the active provider can draft a commit message, review your staged changes, or review a pull request. Prompts are piped over stdin, so a large staged diff is reviewed in full rather than truncated at the command-line limit, and a saved review lands in .beardgit/reviews/. Each action checks there is something to talk about first, so you never get an answer about an empty diff.

None of this has to be on. One switch in Settings → General → Integrations turns the whole AI side off: no CLI probing at launch, no AI views, no AI actions, no process polling. Runs already in flight finish, and the history stays readable.

5 · The .http workspace

Requests live in the repository, as plain files under .beardgit/requests/. Commit them and the rest of the team gets them with a git pull. The panel seeds a small Quickstart collection the first time you open it, so there is something to run immediately.

The file format

A request is a name, a method and URL, headers, a blank line, then a body:

# @name Create a post
POST {{base_url}}/posts
Content-Type: application/json
Authorization: Bearer {{api_token}}

{
  "title": "hello from BeardGit",
  "userId": 1
}

What the parser accepts, exactly:

  • GET POST PUT PATCH DELETE HEAD OPTIONS, case-insensitive. Anything else is an error with the line number.
  • Headers run until the first blank line, as Name: value.
  • Everything after that blank line is the body, verbatim — comments are not stripped there.
  • Lines starting with # or // are comments, before the request line and among the headers.
  • # @name Something names the request. Only that spelling — // @name does nothing.
  • A line starting with ### separates blocks, and the rest of that line is a name.

One request per file, for now. The parser understands several blocks, but the panel runs the first one. There are no scripts, no assertions and no @variable declarations inside a .http file.

Variables and environments

An environment is a JSON file at .beardgit/requests/_env/<name>.json, and the filename is the environment's name:

{
  "$schema": "beardgit-env/v1",
  "vars": {
    "base_url": "https://api.example.com",
    "post_id": "1"
  },
  "secrets": ["api_token"]
}

vars are plain text and safe to commit. secrets lists names only — the values are encrypted on your machine, never in the file. {{name}} is substituted in the URL, in header names and values, and in the body, and resolves in this order: a per-run override you type in the panel, then a secret, then a variable. A name that resolves to nothing fails the request instead of quietly sending an empty string.

Which environment is active is not stored in the repository — it lives in BeardGit's local database, so two people sharing the same files can be pointed at different environments.

Limits worth knowing before you blame the app

  • Loopback and private addresses are refused. A request to localhost, a 192.168.* host or a link-local address is blocked unless you launch the app with BEARDGIT_REQUESTS_ALLOW_PRIVATE=1. It's a guard against a committed request file reaching your own network, not an oversight.
  • 30-second timeout, and redirects are not followed — you see the 301 rather than what it points at.
  • Response bodies are kept up to 5 MiB and flagged as truncated past that.
  • History keeps the last 50 runs per request, with the request as it was actually sent — which means a resolved secret is in that local database in plain text. It never leaves your machine, but it is there.
  • The response diff compares bodies, not status codes or headers.

6 · Themes, including your own

Settings → Look & feel lists the 31 bundled themes. Each has a dark and a light variant that pair up, so the app can follow your OS. The theme colours the whole app — the editor's syntax palette, diff backgrounds and graph lanes included.

Writing one

Drop a .toml file in the themes/ folder next to your settings (the exact path is in § 9; the app writes a README there with the same template). The filename doesn't matter — the [meta] id is the identity, and reusing a built-in id replaces that theme.

Only two sections are required: [meta] and the 18 colours of [colors].

[meta]
id = "my-theme"
name = "My Theme"
mode = "dark"            # "dark" or "light", nothing else

[colors]
background = "#111111"
foreground = "#eeeeee"
black = "#333333"
red = "#ff0000"
green = "#00ff00"
yellow = "#ff8800"
blue = "#0000ff"
magenta = "#8800ff"
cyan = "#00ffff"
white = "#cccccc"
bright-black = "#999999"
bright-red = "#ff4444"
bright-green = "#44ff44"
bright-yellow = "#ffaa44"
bright-blue = "#4444ff"
bright-magenta = "#aa44ff"
bright-cyan = "#44ffff"
bright-white = "#ffffff"

Everything else — accents, text levels, borders, the ten graph lanes, the editor's syntax colours — is derived from those. Override any of it with the optional [accents], [derived], [graph] and [editor] sections, where a value you pin is used as-is:

[accents]
primary = "cyan"          # an ANSI name (underscored) or a hex value

[derived]
text-secondary = "#969ead"

[graph]
lane-colors = ["#7aa2f7", "#9ece6a", "#ff9e64"]   # at least two
node-radius = 5.0

[editor]
added-bg = "#1b3829"
syntax-keyword = "#ff7b72"

Colour formats: #RRGGBB, #RRGGBBAA and rgba(…) only. Short hex (#abc) and rgb(…) are rejected, and a file that fails to parse is skipped silently — if your theme doesn't appear in the list, that is the first thing to check. Both bright-black and bright_black spellings work.

The contrast report

When a theme is applied, BeardGit measures five tokens — the three text levels and the two border levels — against each surface they're drawn on, and reports anything below the WCAG floor (4.5:1 for text, 3.0:1 for the strong border, 2.0:1 for the quiet one). It is advisory: the picker tells you which tokens fall short and by how much, and applies your theme exactly as written. Colours it can't measure, like rgba(…), are listed as unaudited. Every bundled theme clears the floor, and a test keeps it that way.

7 · The keyboard, in full

This is the complete list of registered shortcuts. ? inside the app shows the same thing, generated from the same registry, and ⌘⇧P lets you run any of them by name. On Linux and Windows every below is Ctrl.

Views

16Graph, Changes, Branches, Tags, Stashes, Worktrees
,Settings
PCommand palette
?Shortcut cheat sheet

Git

FFetch
LPull
KPush
BNew branch
SStage everything
UUnstage everything
EOpen the current diff's file in the editor

Graph

J / KNext / previous commit
Home / EndFirst / last commit
/ or FFocus the commit search

Tabs, panes and background work

/ Next / previous project tab
WClose the active tab
BCollapse or expand the sidebar
TNew terminal tab
JTasks popover
ANew AI background run

Inside a list

/ Move the cursor in the changes list
/ Select a range of files
SpaceStage or unstage the file under the cursor
EnterOpen its diff
[ / ]Previous / next file, in a pull or merge request

Enter commits from the message box, but that one is wired to the Command key literally, so on Linux and Windows you'll need the button for now.

8 · A tour of Settings

  • General → Integrations — one switch for GitHub/GitLab, one for AI. Off, the matching surfaces disappear and nothing runs behind them. Both off leaves a git-only client. Your accounts and preferences are kept for when you turn them back on.
  • General → Updates — whether to check for updates at launch, plus the endpoint and the last-check timestamp, so a 404 is distinguishable from no network.
  • Look & feel — theme, follow-the-OS pairing, and the contrast report for whatever is applied.
  • AI — which provider to prefer, how many background runs may run at once, and where their worktrees go.
  • Git — the Test signing button, which signs a throwaway commit and shows you the real error if your SSH, GPG or X.509 setup isn't right.
  • Advanced — the log level (error, info or debug, applied live), a button to open the log folder, and one to clear the cached graph layouts.
  • Sidebar — reorder the navigation, hide what you don't use, reset to default. That layout is app-wide.

9 · Where your data lives

On your machine

One folder holds everything:

macOS~/Library/Application Support/beardgit/
Linux~/.config/beardgit/ (or $XDG_CONFIG_HOME/beardgit/)
Windows%APPDATA%\beardgit\
FileWhat it is
settings.jsonEvery preference, your open and recent repositories, and the list of connected forge accounts
credentials.encForge tokens and request secrets, encrypted
data.dbCommit cache
requests.dbGlobal request collections, response history, and which environment is active per project
themes/Your own .toml themes, plus a README with the template
layouts/, project-cache/Cached graph layouts and per-project scratch data. Safe to delete; Settings → Advanced has a button for the layouts

Logs are elsewhere, one file per day named beardgit.<date>.log, purged after a week:

macOS~/Library/Logs/BeardGit/
Linux~/.local/share/beardgit/logs/
Windows%APPDATA%\BeardGit\logs\

Tokens, Authorization headers and credentials embedded in URLs are replaced with <redacted> on the way into the file, so a log you attach to an issue doesn't carry your keys. Prose, URLs that can hold a credential and shell input are kept out by design.

How the encryption works, and what it doesn't do

Tokens are encrypted with AES-256-GCM under a key derived from an identifier of the machine — the platform UUID on macOS, /etc/machine-id on Linux, the registry's MachineGuid on Windows. That means the file is useless on another computer: a stray copy in a backup, a synced folder or an accidental commit gives nothing away.

It is not protection against something running as you on your own machine — anything with your user account can derive the same key. Moving to the OS keychain is the intended next step. Said plainly because a security claim you have to read the source to qualify isn't worth much.

Inside your repository

Everything BeardGit writes into a project goes under .beardgit/:

PathWhat it isCommit it?
requests/Your .http filesYes — that's the point
requests/_env/*.jsonEnvironment variables; secrets by name onlyYes
favorites.jsonYour starred branchesYour call — commit it to share them with the team
ai-worktrees/The isolated worktrees AI runs happen inNo
ai-reports/The Markdown report each AI run leaves behindNo
reviews/AI reviews you chose to saveNo

The .gitignore BeardGit can write for a new repository does not mention .beardgit/, so the local-only folders above are not ignored for you. If you want to share your requests but not the AI scratch space, add this yourself:

.beardgit/ai-worktrees/
.beardgit/ai-reports/
.beardgit/reviews/

What the app sends over the network on its own

One thing: the update check, described in § 10. With the forge integration on it also validates each saved token at launch and resolves your origin remote against the forge API; with AI on it looks for the three CLIs locally, which is a subprocess, not a request. Turn both integrations off and the updater poll is the only outbound traffic left — and it has its own switch. There is no telemetry, no analytics and no crash reporter anywhere in the app.

10 · Updates

BeardGit checks once at launch, against a single URL — the latest.json attached to the newest GitHub release — and no more than once a minute across restarts. It never asks in a dialog you didn't open: if there's a newer version you get a quiet notice, and installing is your click. If the check fails, it fails silently rather than nagging you about your network.

Version numbers are year.month.release, so 26.9.1 is the second release of September 2026. The updater only offers something strictly newer, and Settings → General shows the endpoint and last-check time when you need to tell a 404 apart from a DNS hiccup. Turn the whole thing off there if you'd rather update by hand.

On macOS and Windows the installer replaces the app, and on Windows it closes BeardGit mid-install — nothing that would be shown after the download is worth reading, which is why the unsigned-build notice appears before you start.

11 · When something misbehaves

"BeardGit is damaged and can't be opened"
Gatekeeper, not a bad download. xattr -dr com.apple.quarantine /Applications/BeardGit.app, once.
A commit, push or rebase fails but reads look fine
Writes use your system git. Check git --version in a terminal — the app doesn't verify it at startup.
Commit signing fails
Settings → Git → Test signing. It signs a throwaway commit and shows the actual error from your signer, which is usually a missing key or an agent that isn't running.
GitLab actions fail while GitHub works
Since 26.9.1 BeardGit uses its own bundled glab, which fixed exactly this: an old glab on your PATH couldn't read the config a current one writes. Update to the latest release.
The terminal mangles accents, or Ctrl+R and fzf leave rubbish on screen
Fixed in 26.9.1. Opening the app from a launcher gave the shell no TERM or locale, so anything drawing in raw mode broke. Update.
A request to localhost is refused
Deliberate. Start the app with BEARDGIT_REQUESTS_ALLOW_PRIVATE=1 to allow loopback and private addresses.
My theme doesn't show up in the list
A theme file that doesn't parse is skipped without a message. The usual causes are a short hex value like #abc, an rgb(…) value, a missing colour, or a mode that isn't exactly dark or light.
The graph looks stale after something changed outside the app
Settings → Advanced → clear the cached layouts, then reopen the repository. Worth reporting if it happens twice.
Anything else
Settings → Advanced → set the log level to debug, reproduce it, then open the log folder from the same page. Attach the file — it is redacted — to an issue, with your OS and the version from Help → About.

12 · Building from source

You need Rust (the version is pinned in rust-toolchain.toml), Node 22 and git.

git clone https://github.com/The3eard/BeardGit.git
cd BeardGit
npm install
npm run tauri dev

The first build compiles every Rust crate and takes a few minutes; after that it's quick. npm run tauri build produces the installer for your platform.

Platform prerequisites:

  • macOSxcode-select --install
  • Debian / Ubuntulibwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
  • Archwebkit2gtk-4.1 base-devel curl wget file openssl appmenu-gtk-module libappindicator-gtk3 librsvg xdotool
  • Fedorawebkit2gtk4.1-devel openssl-devel curl wget file libappindicator-gtk3-devel librsvg2-devel libxdo-devel plus the C development group
  • Windows — MSVC Build Tools with "Desktop development with C++", and the WebView2 Runtime

Contributions are welcome — CONTRIBUTING.md has the branch conventions and the checks a change has to pass.

13 · Uninstalling

Remove the app the way your OS does it: drag it out of /Applications, delete the AppImage, or use Add/Remove programs. That leaves your data behind on purpose. To remove that too, delete the config folder and the log folder from § 9.

Two things worth remembering before you do: credentials.enc holds your forge tokens and request secrets, and the tokens themselves are still valid on the forge — revoke them there if that's what you meant. And anything under .beardgit/ in a repository stays with the repository until you delete it, including AI worktrees, which are real git worktrees. Removing them through the Worktrees view keeps git's bookkeeping straight.