Configuration
Set stacks defaults in config.json and environment variables, and find where it keeps data, state and caches on disk.
# Configuration
> Set stacks defaults in config.json and environment variables, and find where it keeps data, state and caches on disk.
stacks works with no configuration. Everything on this page is optional: a `config.json` for defaults you'd otherwise pass as flags, and environment variables for paths, logging, network and telemetry.
## config.json
The file lives at `~/.config/stacks/config.json`, or `$XDG_CONFIG_HOME/stacks/config.json` when that's set. A missing file is fine.
```json title="~/.config/stacks/config.json"
{
"agents": ["claude", "codex"],
"always": ["git-hooks"],
"author": "A. Name",
"package_scope": "@acme",
"preset": "sandbox"
}
```
| Key | Meaning |
| --- | --- |
| `agents` | Agents whose `adapters/<agent>/` files are written: any of `claude`, `codex`, `opencode`, `cursor`. `--agents` overrides it. Default `["claude"]` |
| `always` | Fragment ids added to every composition they fit. One that doesn't fit, or doesn't exist, is skipped with a warning. `--without` still removes one |
| `author` | Author name for templates. `--author` overrides it; without either, stacks uses `git config user.name` |
| `package_scope` | npm scope for templates, such as `@acme`. `--scope` overrides it |
| `preset` | `default` or `sandbox` for `new`. `--preset` and `--sandbox` override it |
| `dataDir` | Data directory. `STACKS_DATA_DIR` overrides it |
| `telemetry` | `false` turns off anonymous usage telemetry. Prefer `stacks telemetry disable`, which also deletes pending events and identity |
The schema is closed: any other key is an error, reported as `InvalidConfig` (exit 3). Environment variables override file values, and blank values count as absent.
stacks reads the file lazily, once per invocation, so `--help`, `--version` and `stacks doctor` still work when it's broken. `doctor` reports a malformed file under `configErrors` and exits 0, so run it to find the problem:
```sh title="Terminal"
stacks doctor
```
Your own stacks and fragments live beside this file, in `stacks/<id>/` and `fragments/<id>/`. That directory is the trusted `user` origin; see [Registries and trust](https://stacks.steamfield.io/docs/concepts/registries-and-trust.md).
## Environment variables
### Paths
| Variable | Meaning |
| --- | --- |
| `STACKS_DATA_DIR` | Data directory. Default `$XDG_DATA_HOME/stacks` (`~/.local/share/stacks`) |
| `STACKS_STATE_DIR` | Project state records and telemetry state. Default `$XDG_STATE_HOME/stacks` (`~/.local/state/stacks`) |
| `HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME` | Path roots. The cache is `$XDG_CACHE_HOME/stacks` (`~/.cache/stacks`) |
### Registry and network
| Variable | Meaning |
| --- | --- |
| `STACKS_INDEX_URL` | Read entries from a different registry index instead of the default signed one. HTTPS only, except plain HTTP on `localhost` or `127.0.0.1`. An invalid URL is never fetched. Its entries are untrusted, and published stats are turned off |
| `STACKS_REGISTRY_DIR` | A directory used in place of the bundled registry, relative to the working directory. Its entries are untrusted |
| `STACKS_OFFLINE` | `1` turns off every network request: index refreshes, stats, search API calls and telemetry. Verified cached entries stay available. Same as `--offline` |
### Telemetry
| Variable | Meaning |
| --- | --- |
| `DO_NOT_TRACK` | Any value except empty, `0` or `false` turns off telemetry and keeps `stacks search` requests on this machine |
| `STACKS_TELEMETRY_DISABLED` | Any value except empty, `0` or `false` turns off telemetry. Doesn't affect search |
| `CI` | Any set value, even empty, turns off telemetry and selects agent output at a terminal |
| `STACKS_TELEMETRY_DEBUG` | `1` prints each event to stderr instead of queuing or sending it. Consent rules still apply |
| `STACKS_TELEMETRY_URL` | Send events to a different server, for testing your own collector |
[Telemetry](https://stacks.steamfield.io/docs/reference/telemetry.md) covers the commands and the order these switches are checked in.
### Output and logging
| Variable | Meaning |
| --- | --- |
| `NO_COLOR` | Any nonempty value turns off color and the live progress line. Wins over `FORCE_COLOR` |
| `FORCE_COLOR` | `1` colors human output on a stderr that isn't a terminal, as long as stdout is one |
| `STACKS_LOG_FILE` | Path to a JSONL log file. Its directory is created when needed |
| `STACKS_LOG_FORMAT` | `json` for JSON diagnostics, otherwise plain readable logs |
| `LOG_LEVEL` | `trace`, `debug`, `info`, `warn`, `error`, `fatal` or `none`. Default `warn`, which is also the fallback for an invalid value |
[Output, JSON and exit codes](https://stacks.steamfield.io/docs/reference/output.md) explains when logs reach stderr.
## Shared flags
Every command accepts these, in addition to its own flags:
| Flag | What it does |
| --- | --- |
| `--json` | Write one JSON result to stdout. A failure writes one JSON error envelope as the last stderr line |
| `--offline` | Use cached and bundled entries without network requests. Same as `STACKS_OFFLINE=1` |
| `--no-telemetry` | Skip telemetry for this invocation, keeping queued events |
| `--log-level` | Minimum log level for this invocation |
## Files on disk
| Path | What's there |
| --- | --- |
| `~/.config/stacks/config.json` | Optional settings |
| `~/.config/stacks/stacks/`, `~/.config/stacks/fragments/` | Your own entries |
| `~/.local/state/stacks/projects/<projectId>.json` | Each project's state record: the second copy of its verify digest and its timings |
| `~/.local/state/stacks/telemetry/` | Telemetry consent, identity and pending events |
| `~/.cache/stacks/index/` | The verified registry index and extracted entry bundles |
| `~/.cache/stacks/stats/` | Cached published stats, one state file per resource |
| `~/.cache/stacks/search/backoff.json` | Search API backoff: endpoint URLs and expiry times only |
Every cache can be deleted safely; stacks rebuilds it on the next request. Deleting a project's state record turns its tamper check into `manifest-only` until `stacks verify --accept-changes` writes a new one.
## Network requests
stacks sends every request to one host, https://stacks.steamfield.io:
| Request | When | Deadline | On failure |
| --- | --- | --- | --- |
| Registry index and entry bundles | `list`, `show`, `new` and `add`, when the cached index is over 24 hours old | 1,500 ms | Last verified index or the bundled registry; retry after ten minutes, or 24 hours after a 404 |
| Published stats | `list` and `show`, when the cached copy is over 24 hours old | 1,500 ms | No stats shown; retry after ten minutes, or 24 hours after a 404 |
| Search | `stacks search`, unless `--local` | 800 ms | Local ranking; retry after ten minutes |
| Signed dependency allowlist | `new`, when the cached copy is over 24 hours old | 1,500 ms | Last verified copy, or none; retry after ten minutes |
| Telemetry events | After `verify`, before `new` or `add` hands off to an agent, and `stacks telemetry flush` | 800 ms (5 seconds for `flush`) | Events stay queued; retry after ten minutes |
`--offline` or `STACKS_OFFLINE=1` turns all of them off. [Telemetry](https://stacks.steamfield.io/docs/reference/telemetry.md) covers when events are sent and the other ways to stop them. `stacks verify` never makes registry, stats or search requests.
`stacks doctor --json` reports the index cache's state under `remoteIndex` without contacting the server. [Registries and trust](https://stacks.steamfield.io/docs/concepts/registries-and-trust.md#the-signed-index) explains what the CLI verifies before using an index.
View as MarkdownOpen in ClaudeOpen in ChatGPTstacks works with no configuration. Everything on this page is optional: a config.json for defaults you'd otherwise pass as flags, and environment variables for paths, logging, network and telemetry.
config.json
The file lives at ~/.config/stacks/config.json, or $XDG_CONFIG_HOME/stacks/config.json when that's set. A missing file is fine.
{
"agents": ["claude", "codex"],
"always": ["git-hooks"],
"author": "A. Name",
"package_scope": "@acme",
"preset": "sandbox"
}| Key | Meaning |
|---|---|
agents |
Agents whose adapters/<agent>/ files are written: any of claude, codex, opencode, cursor. --agents overrides it. Default ["claude"] |
always |
Fragment ids added to every composition they fit. One that doesn't fit, or doesn't exist, is skipped with a warning. --without still removes one |
author |
Author name for templates. --author overrides it; without either, stacks uses git config user.name |
package_scope |
npm scope for templates, such as @acme. --scope overrides it |
preset |
default or sandbox for new. --preset and --sandbox override it |
dataDir |
Data directory. STACKS_DATA_DIR overrides it |
telemetry |
false turns off anonymous usage telemetry. Prefer stacks telemetry disable, which also deletes pending events and identity |
The schema is closed: any other key is an error, reported as InvalidConfig (exit 3). Environment variables override file values, and blank values count as absent.
stacks reads the file lazily, once per invocation, so --help, --version and stacks doctor still work when it's broken. doctor reports a malformed file under configErrors and exits 0, so run it to find the problem:
stacks doctorYour own stacks and fragments live beside this file, in stacks/<id>/ and fragments/<id>/. That directory is the trusted user origin; see Registries and trust.
Environment variables
Paths
| Variable | Meaning |
|---|---|
STACKS_DATA_DIR |
Data directory. Default $XDG_DATA_HOME/stacks (~/.local/share/stacks) |
STACKS_STATE_DIR |
Project state records and telemetry state. Default $XDG_STATE_HOME/stacks (~/.local/state/stacks) |
HOME, XDG_CONFIG_HOME, XDG_DATA_HOME, XDG_STATE_HOME, XDG_CACHE_HOME |
Path roots. The cache is $XDG_CACHE_HOME/stacks (~/.cache/stacks) |
Registry and network
| Variable | Meaning |
|---|---|
STACKS_INDEX_URL |
Read entries from a different registry index instead of the default signed one. HTTPS only, except plain HTTP on localhost or 127.0.0.1. An invalid URL is never fetched. Its entries are untrusted, and published stats are turned off |
STACKS_REGISTRY_DIR |
A directory used in place of the bundled registry, relative to the working directory. Its entries are untrusted |
STACKS_OFFLINE |
1 turns off every network request: index refreshes, stats, search API calls and telemetry. Verified cached entries stay available. Same as --offline |
Telemetry
| Variable | Meaning |
|---|---|
DO_NOT_TRACK |
Any value except empty, 0 or false turns off telemetry and keeps stacks search requests on this machine |
STACKS_TELEMETRY_DISABLED |
Any value except empty, 0 or false turns off telemetry. Doesn't affect search |
CI |
Any set value, even empty, turns off telemetry and selects agent output at a terminal |
STACKS_TELEMETRY_DEBUG |
1 prints each event to stderr instead of queuing or sending it. Consent rules still apply |
STACKS_TELEMETRY_URL |
Send events to a different server, for testing your own collector |
Telemetry covers the commands and the order these switches are checked in.
Output and logging
| Variable | Meaning |
|---|---|
NO_COLOR |
Any nonempty value turns off color and the live progress line. Wins over FORCE_COLOR |
FORCE_COLOR |
1 colors human output on a stderr that isn't a terminal, as long as stdout is one |
STACKS_LOG_FILE |
Path to a JSONL log file. Its directory is created when needed |
STACKS_LOG_FORMAT |
json for JSON diagnostics, otherwise plain readable logs |
LOG_LEVEL |
trace, debug, info, warn, error, fatal or none. Default warn, which is also the fallback for an invalid value |
Output, JSON and exit codes explains when logs reach stderr.
Shared flags
Every command accepts these, in addition to its own flags:
| Flag | What it does |
|---|---|
--json |
Write one JSON result to stdout. A failure writes one JSON error envelope as the last stderr line |
--offline |
Use cached and bundled entries without network requests. Same as STACKS_OFFLINE=1 |
--no-telemetry |
Skip telemetry for this invocation, keeping queued events |
--log-level |
Minimum log level for this invocation |
Files on disk
| Path | What's there |
|---|---|
~/.config/stacks/config.json |
Optional settings |
~/.config/stacks/stacks/, ~/.config/stacks/fragments/ |
Your own entries |
~/.local/state/stacks/projects/<projectId>.json |
Each project's state record: the second copy of its verify digest and its timings |
~/.local/state/stacks/telemetry/ |
Telemetry consent, identity and pending events |
~/.cache/stacks/index/ |
The verified registry index and extracted entry bundles |
~/.cache/stacks/stats/ |
Cached published stats, one state file per resource |
~/.cache/stacks/search/backoff.json |
Search API backoff: endpoint URLs and expiry times only |
Every cache can be deleted safely; stacks rebuilds it on the next request. Deleting a project's state record turns its tamper check into manifest-only until stacks verify --accept-changes writes a new one.
Network requests
stacks sends every request to one host, https://stacks.steamfield.io:
| Request | When | Deadline | On failure |
|---|---|---|---|
| Registry index and entry bundles | list, show, new and add, when the cached index is over 24 hours old |
1,500 ms | Last verified index or the bundled registry; retry after ten minutes, or 24 hours after a 404 |
| Published stats | list and show, when the cached copy is over 24 hours old |
1,500 ms | No stats shown; retry after ten minutes, or 24 hours after a 404 |
| Search | stacks search, unless --local |
800 ms | Local ranking; retry after ten minutes |
| Signed dependency allowlist | new, when the cached copy is over 24 hours old |
1,500 ms | Last verified copy, or none; retry after ten minutes |
| Telemetry events | After verify, before new or add hands off to an agent, and stacks telemetry flush |
800 ms (5 seconds for flush) |
Events stay queued; retry after ten minutes |
--offline or STACKS_OFFLINE=1 turns all of them off. Telemetry covers when events are sent and the other ways to stop them. stacks verify never makes registry, stats or search requests.
stacks doctor --json reports the index cache's state under remoteIndex without contacting the server. Registries and trust explains what the CLI verifies before using an index.