stage keeps one configuration file. The settings modal writes to it, and you can write to it yourself. Both are the same file.
To find it, press ; and read the config row of the About section. To open
it, press e from the settings.
Its shape
Section titled “Its shape”The file mirrors lazygit’s, down to the names of the leaves:
{ "gui": { "theme": "auto", "sidePanelWidth": 0.3, "showFileTree": false }, "git": { "pull": { "mode": "auto" }, "autoFetch": true }}A lazygit configuration is therefore readable here, and stage --import
translates one for you. Read Coming from lazygit.
The sections with pages of their own
Section titled “The sections with pages of their own”| Section | Page |
|---|---|
keys |
Keybindings |
customCommands |
Custom commands |
theme, themeLight, themeDark |
Theme |
Language servers
Section titled “Language servers”lsp and codeNav control go-to-definition.
{ "codeNav": true, "lsp": { "rust": false, "typescript": { "command": ["typescript-language-server", "--stdio"] } }}false for a server turns that server off. lsp: false turns the whole feature
off. codeNav is the switch the settings modal uses.
The two are separate on purpose. Turning the feature off from the settings must not delete the map of servers you configured.
Forge hosts
Section titled “Forge hosts”services names a self-hosted GitHub or GitLab, for the pull request commands:
{ "services": { "git.acme.com": "github:git.acme.com" } }github.com and gitlab.com need nothing here.
Pull mode
Section titled “Pull mode”pullMode decides how pull brings work in. auto is the default, and it adds
no flag at all — your pull.rebase and pull.ff settings decide.
That is deliberate. git already answers this question, and two answers in two places disagree sooner or later.
Command line
Section titled “Command line”| Flag | Effect |
|---|---|
--theme <id>, -t |
Use a theme for one run |
--import [path] |
Translate a lazygit configuration |
--version, -v |
Print the version |
--help, -h |
Print the usage |
Environment
Section titled “Environment”| Variable | Effect |
|---|---|
STAGE_NO_FFF=1 |
Start without the search engine |
STAGE_NO_LSP=1 |
Start without language servers |
STAGE_NO_HOST=1 |
Detect no agent terminal |
STAGE_NO_HERDR=1 |
Ignore herdr |
STAGE_NO_CMUX=1 |
Ignore cmux |
Every key
Section titled “Every key”Generated from StageConfig and its own doc comments. A default is shown only
where the code exports one. The rest state theirs in the description.
| Key | Type | Default | What it does |
|---|---|---|---|
theme |
string |
— | Any hunkdiff theme id, e.g. “github-dark-default”, or “auto” to follow the terminal’s light/dark background (OSC 11). |
themeLight |
string |
— | Theme “auto” resolves to this id on a light terminal (default github-light-default). |
themeDark |
string |
— | Theme “auto” resolves to this id on a dark terminal (default github-dark-default). |
diffLayout |
DiffLayoutMode |
— | Read-only diff layout; “auto” (default) picks split when the pane is wide. Values: "auto" · "split" · "stack". |
wrap |
boolean |
— | Wrap long lines (diff views, staging editor, commit bodies) instead of clipping. |
sidebarWidth |
number |
0.3 |
Sidebar width as a fraction of the terminal (lazygit’s sidePanelWidth). Drag the gap between the sidebar and the main pane to change it. Values: 0.2 · 0.25 · 0.3 · 0.35 · 0.4. |
sidebarSide |
SidebarSide |
— | Which side the sidebar sits on; default “left”. Values: "left" · "right". |
screenMode |
ScreenMode |
— | Screen mode the app starts in, and returns to on a reload — see ScreenMode. Values: "normal" · "half" · "full". |
diffContext |
number |
3 |
Context lines around view-diff hunks (lazygit’s diffContextSize). |
renameThreshold |
number |
50 |
Rename-detection similarity threshold, percent (lazygit’s git.renameSimilarityThreshold); )/( nudge it live. |
scrollSpeed |
number |
2 |
Rows one j/k scrolls the main diff pane (lazygit’s scrollHeight). |
confirmOnQuit |
boolean |
— | Ask before quitting on q (ctrl+c always quits immediately). |
transparentBackground |
boolean |
— | Stop painting neutral surfaces so terminal transparency shows through. |
fileTree |
boolean |
— | Files panel as a collapsible directory tree instead of flat paths. |
commandLog |
boolean |
— | Show the command-log strip at startup (@ toggles it for the session). |
commitGraph |
boolean |
— | Graph lanes in the commits panel (lazygit’s git.log.showGraph; default on). |
worktreeDefaultPath |
string |
— | Default parent directory offered for new worktrees: relative = against the repo root, ~ expands. STAGE-ONLY — lazygit has no worktree config section at all (its only worktrees key is a keybinding group). |
explorerIgnored |
boolean |
— | Show gitignored entries (greyed) in the explorer; default on. |
pullMode |
PullMode |
— | How pull integrates upstream work: “auto” (default) adds no flag and defers to git’s own pull.rebase/pull.ff config — modern lazygit’s stance (it removed git.pull.mode for exactly this reason). The explicit modes exist for control from stage without touching git config. Values: "auto" · "merge" · "rebase" · "ff-only". |
branchSort |
BranchSort |
— | Local-branch order in the branches panel (lazygit’s s menu / git.localBranchSortOrder). “recency” = last checked out first. Values: "recency" · "alphabetical" · "date". |
remoteBranchSort |
RemoteBranchSort |
— | Remote-branch order in the remotes tab (lazygit’s remoteBranchSortOrder); no “recency” — the reflog only records local checkouts. Values: "alphabetical" · "date". |
autoFetch |
boolean |
— | Background git fetch on an interval (lazygit’s git.autoFetch; default on). Quiet on failure and constructionally unable to prompt for credentials. |
autoFetchInterval |
number |
60 |
Seconds between background fetches (lazygit’s refresher.fetchInterval). |
disableForcePushing |
boolean |
— | Never offer a force push (lazygit’s git.disableForcePushing; default off). A rejected push then reports what happened and stops, so nothing stage offers can discard commits on a remote. |
updateCheck |
boolean |
— | At launch, stage asks GitHub for the newest release, one time each day (default on). stage shows a notice and does not install the release. The stage update command installs it. |
keys |
Record<string, unknown> |
— | Keybinding overrides: binding id → lazygit-style key notation, e.g. {“files.stage”: “x”, “global.quit”: “ |
customCommands |
CustomCommand[] |
— | User-defined commands. Structurally-invalid entries are dropped at load; entries whose key/context/template fail validation are reported (and skipped) when compiled, so one bad command never disables the rest. |
services |
Record<string, string> |
— | Custom forge hosts for the browser/PR verbs (lazygit’s services): git-domain → “provider:web-domain”, e.g. {“git.acme.com”: “github:git.acme.com”}. github.com/gitlab.com/etc. work with no config; this only names self-hosted or Enterprise instances. Values are validated where they’re consumed (hostingService), so a bad entry degrades that one host rather than failing load. |
lsp |
false | Record<string, false | { command?: string[] }> |
— | Language servers for code navigation (go-to-definition in file views). false disables the whole feature; a per-server false disables one (keyed by the server id — e.g. “typescript”, “rust”, “go”, “python”); a { command } overrides that server’s spawn argv (also the test hook). Where two servers claim the same files, the faster one is preferred when it is on PATH (“tsgo” over “typescript”, “ty” over “python”) — neither is ever installed by accident, so having it is the request to use it. The other answers when the first is absent, disabled, or failed this session, so {“tsgo”: false} is how you keep tsserver. Absent = the built-in table, discovered on PATH. Read lazily by src/lsp at spawn-resolution time, NOT threaded through Session props. |
codeNav |
boolean |
— | The code-navigation feature master switch (the options-tab “Code nav” toggle). Default true. Kept SEPARATE from lsp so toggling it off/on can’t clobber a user’s per-server map: lsp: false is the hard config-only off, this owns the live toggle. Read lazily by src/lsp at spawn-resolution time. |
30 keys, all optional.