Settings file & environment
The settings file is modde’s primary, cross-platform configuration mechanism: it works the same on Linux, macOS, and Windows, with no Nix required. modde’s configuration state lives in a small set of plain TOML files under your platform config directory, plus a handful of environment variables that override paths and behavior at runtime. The CLI and GUI read and write these files directly. This page documents the on-disk schema, the environment surface, the instance registry, and how all the configuration layers rank against each other.
If you use Nix, you can additionally declare profiles as code through the home-manager module; that is one option layered on top of the same runtime, not a replacement for the settings file.
The authoritative sources are
crates/modde-core/src/settings.rs,
crates/modde-core/src/paths.rs,
and
crates/modde-core/src/instance.rs.
settings.toml
Location
settings.toml lives in modde’s config directory, <config_dir>/modde/:
| OS | Config dir | Full path |
|---|---|---|
| Linux | $XDG_CONFIG_HOME, else ~/.config | ~/.config/modde/settings.toml |
| macOS | ~/Library/Application Support | ~/Library/Application Support/modde/settings.toml |
| Windows | %APPDATA% (e.g. C:\Users\X\AppData\Roaming) | %APPDATA%\modde\settings.toml |
On Linux, setting XDG_CONFIG_HOME relocates the directory. The file is written
with toml::to_string_pretty, so it stays human-readable and hand-editable.
Loading behavior
Settings loading is forgiving by design:
- A missing file loads as all-defaults.
- A malformed file (parse error) also falls back to all-defaults rather than erroring.
- Unknown keys are ignored, so a newer file does not break an older binary.
- Missing keys are filled with their defaults, so a partial file is valid.
Keys
| Key | Type | Default | Description |
|---|---|---|---|
nexus_api_key | string | "" | Legacy inline Nexus API key (lowest-precedence key source — prefer the keyring or nexus auth) |
game_paths | array of { game_id, path } | [] | Configured game install paths (typically 1–4 games) |
download_dir | path (optional) | unset | Override for the downloads directory |
theme | string | "" | UI theme name (e.g. Nord); empty means the built-in default |
selected_game | string (optional) | unset | The game last selected in the UI |
update_check.enabled | bool | true | Whether modde checks for newer releases on startup |
nexus_api_key is serialized only when non-empty, so a clean settings file does
not contain it. It is the legacy key source — modde keeps reading it for
backward compatibility, but it ranks last in the
Nexus key precedence. Prefer modde nexus auth, the
system keyring, or NEXUS_API_KEY / NEXUS_API_KEY_FILE.
game_paths is an array of tables; each entry pairs a game_id with its install
path. modde looks up a game’s path by game_id, and setting a path either adds
a new entry or updates the existing one (no duplicates).
Example
nexus_api_key = "legacy-key-if-you-must"
download_dir = "/data/modde/downloads"
theme = "Nord"
selected_game = "cyberpunk2077"
[[game_paths]]
game_id = "cyberpunk2077"
path = "/data/games/Cyberpunk 2077"
[[game_paths]]
game_id = "skyrim-se"
path = "/data/games/Skyrim Special Edition"
[update_check]
enabled = true
A minimal file is equally valid — every omitted key falls back to its default:
selected_game = "skyrim-se"
Data, cache, and downloads directories
settings.toml only stores configuration; modde’s actual mod store, profiles,
database, and downloads live under the data directory, which is separate from
the config directory and platform-aware:
| OS | Data dir base |
|---|---|
| Linux | $XDG_DATA_HOME, else ~/.local/share |
| macOS | ~/Library/Application Support |
| Windows | %APPDATA% |
modde’s data root is <data_dir>/modde/ (unless overridden — see
Precedence), with this layout:
| Path | Purpose |
|---|---|
<modde_data>/store/ | Content-addressed mod file store |
<modde_data>/staging/ | Staging scratch space |
<modde_data>/profiles/ | Per-profile state |
<modde_data>/downloads/ | Default downloads directory |
<modde_data>/stock/ | Stock (vanilla) game snapshots |
<modde_data>/saves/ | Save vaults (one git repo per game) |
<modde_data>/wabbajack_cache/ | Cached .wabbajack manifest files |
<modde_data>/modde.db | SQLite database |
The cache directory is <cache_dir>/modde/ ($XDG_CACHE_HOME or ~/.cache on
Linux, ~/Library/Caches on macOS, %LOCALAPPDATA% on Windows). The downloads
directory defaults to <modde_data>/downloads/; the download_dir key in
settings.toml overrides it.
Environment variables
modde honors the following environment variables:
| Variable | Effect |
|---|---|
MODDE_DATA_DIR | Override the data directory. Equivalent to the global --data-dir flag (the flag wins if both set) |
NEXUS_API_KEY | Nexus API key, read directly from the environment (see precedence) |
NEXUS_API_KEY_FILE | Path to a file containing the Nexus API key — sops-nix / agenix friendly; set by the home-manager module |
MODDE_NO_UPDATE_CHECK | When set to 1/true/yes/on, disables the startup update check regardless of settings.toml |
MODDE_UPDATE_CHECK_URL | Override the release endpoint queried by the update check (defaults to the Codeberg releases API) |
XDG_CONFIG_HOME | Linux: relocates the config dir (and therefore settings.toml and instances.toml) |
XDG_DATA_HOME | Linux: relocates the data dir base |
XDG_CACHE_HOME | Linux: relocates the cache dir base |
A few more variables exist for niche purposes: MODDE_HEAP_PROFILE (write a DHAT
heap profile; requires the heap-profile feature), MODDE_CHROMIUM (path to a
Chromium binary used by the Wabbajack login flow), and, only when modde is built
with the optional remote-telemetry feature, RS_MODDE_TELEMETRY_ENDPOINT /
RS_MODDE_TELEMETRY_TOKEN. These are not part of normal configuration.
The global --data-dir CLI flag (backed by MODDE_DATA_DIR) overrides the data
directory for a single invocation, for example:
modde --data-dir /mnt/big/modde profile list
# or, equivalently for the whole session:
MODDE_DATA_DIR=/mnt/big/modde modde profile list
Instance registry (instances.toml)
modde supports multiple instances — independent, self-contained data
directories — registered in <config_dir>/modde/instances.toml (next to
settings.toml). Each instance names a data_dir; one instance can be marked
default, and one is active at a time. When an active instance is set, its
data_dir becomes modde’s data directory (see
Data directory resolution).
Schema:
| Field | Type | Description |
|---|---|---|
active | string (optional) | Name of the currently active instance |
instances | array of { name, data_dir, is_default } | Registered instances |
instances[].name | string | Unique instance name |
instances[].data_dir | path | The instance’s self-contained data directory |
instances[].is_default | bool | Whether this is the default instance |
Example:
active = "modding-rig"
[[instances]]
name = "default"
data_dir = "/home/me/.local/share/modde"
is_default = true
[[instances]]
name = "modding-rig"
data_dir = "/mnt/nvme/modde"
is_default = false
Creating an instance makes a directory and registers it; the first instance
created becomes the default and the active one. Switching changes active.
Instance names must be unique.
Configuration precedence
modde’s configuration comes from several layers. Two precedence chains matter: the data directory resolution and the Nexus API key resolution.
Data directory resolution
The effective data directory is chosen in this order (first match wins):
- Explicit override — the global
--data-dirflag orMODDE_DATA_DIRenvironment variable (the flag takes precedence over the env var). This also wins over an in-process override set at startup. - Active instance — the
data_dirof the active instance ininstances.toml, if one is set. - Default —
<data_dir>/modde/, where<data_dir>honorsXDG_DATA_HOMEon Linux and the platform data directory elsewhere.
Nexus API key precedence
When modde needs a Nexus API key it walks this chain and uses the first source
that yields a non-empty key (from
crates/modde-sources/src/nexus/auth.rs):
- OAuth token — a non-expired token from
modde nexus authOAuth login. - modde config file —
<config_dir>/modde/nexus_api_key, written bymodde nexus auth(created with0600permissions on Unix). NEXUS_API_KEY— the environment variable, read directly.- System keyring — the secret-service / D-Bus keyring entry
(
service = "modde",key = "nexus-api-key"). NEXUS_API_KEY_FILE— a file path; the file’s trimmed contents are used. This is the sops-nix-friendly source that the home-manager module’snexus.apiKeyFileexports.- Legacy
settings.toml— thenexus_api_keykey, kept for backward compatibility and ranked last.
If none yield a key, modde reports
No Nexus API key found. Set NEXUS_API_KEY env var or run "modde nexus auth".
How Nix, the settings file, env vars, and the keyring relate
The layers do not conflict so much as compose:
- The home-manager module owns the declarative surface — profiles,
Wabbajack lists, Nexus collections, and per-tool config — and drives the CLI on
every rebuild. It exports
NEXUS_API_KEY_FILEwhen you setnexus.apiKeyFile, but it does not writesettings.tomlkeys liketheme,download_dir, orselected_game. settings.tomlowns the imperative, user-facing preferences (game paths, download dir, theme, selected game, update-check toggle). The CLI and GUI read and write it. For the Nexus key specifically it is the lowest-precedence source.- Environment variables override at runtime —
MODDE_DATA_DIRfor the data dir,NEXUS_API_KEY/NEXUS_API_KEY_FILEfor the key,MODDE_NO_UPDATE_CHECKfor the update check. They take effect regardless ofsettings.toml. - The system keyring is the recommended interactive store for the Nexus key
(set it with
modde nexus auth); it outranksNEXUS_API_KEY_FILEand the legacysettings.tomlkey, but is itself outranked byNEXUS_API_KEYand the modde-owned config file.
In short: the CLI/GUI manage settings.toml and store the Nexus key in the
keyring or environment on every platform. If you use Nix, you can additionally
declare profiles in the home-manager module and keep the Nexus secret in
nexus.apiKeyFile — layered on top of, not instead of, the settings file.
See also
- Home-Manager module — the declarative configuration surface
- Installation — install channels and the home-manager module import
- Nexus guide — authenticating with Nexus Mods
- Downloads guide — the download directory and backends