Development Preview build — APIs and content may change. Visit ocx.sh for the current release.
Skip to content

Configuration

API reference for OCX configuration files. For the rationale behind the tier model, the merge philosophy, and worked examples, see the Configuration in-depth page.

Config files are in TOML format and are optional. OCX works without any config file using compiled-in defaults.

File Locations

TierPathPurpose
System/etc/ocx/config.tomlMachine-wide defaults
User (Linux)$XDG_CONFIG_HOME/ocx/config.toml or ~/.config/ocx/config.tomlPer-user defaults
User (macOS)~/Library/Application Support/ocx/config.tomlPer-user defaults; XDG_CONFIG_HOME not consulted
OCX home$OCX_HOME/config.toml (default: ~/.ocx/config.toml)Co-located with data; survives a zip-and-move of $OCX_HOME

Missing files are silently skipped.

Explicit additions

Two mechanisms add a file on top of the discovery chain — they do not replace it. Missing files are an error in this case (explicit paths must exist).

  • --config FILE — CLI flag, before subcommand
  • OCX_CONFIG=/path/to/file.toml — environment variable

When both are set, --config layers on top of OCX_CONFIG. Setting OCX_CONFIG to the empty string disables an ambient value without unsetting it.

Discovery and Merge Precedence

Settings are resolved lowest-to-highest. Higher-precedence sources override lower ones.

PrioritySourceNotes
1 (lowest)Compiled defaultsBuilt into the OCX binary
2System config — /etc/ocx/config.tomlDiscovered tier
3User config — $XDG_CONFIG_HOME/ocx/config.toml (Linux) or ~/Library/Application Support/ocx/config.toml (macOS)Discovered tier
4OCX home config — $OCX_HOME/config.tomlDiscovered tier
5OCX_CONFIGLayered on top of discovered tiers
6--config FILELayered on top of OCX_CONFIG
7Environment variables (OCX_*)Always win over any config file
8 (highest)CLI flagsPer-invocation; always win

Merge rules

  • Scalars: the nearest (highest-precedence) value wins.
  • Tables (e.g. [registries.<name>]): merged key-by-key across tiers; inner keys use nearest-wins.
  • Layering: every file is loaded and merged in order. Explicit paths do not replace the discovered tiers.

Kill switch

OCX_NO_CONFIG=1 skips the discovered chain only (tiers 2–4). Explicit paths (--config, OCX_CONFIG) still load.

GoalInvocation
Default(no flags)
Layer override on ambient--config extra.toml
Hermetic with a specific fileOCX_NO_CONFIG=1 --config ci.toml
Hermetic, no filesOCX_NO_CONFIG=1

Configuration Keys

[registry]

Global settings for the registry subsystem.

default

Type: string
Default: "ocx.sh"
Overridden by: OCX_DEFAULT_REGISTRY environment variable

The default registry used for bare package identifiers — those without an explicit registry prefix. When you write cmake:3.28, OCX expands it to <default>/cmake:3.28.

The value may be either a literal hostname ("ghcr.io") or the name of a [registries.<name>] entry. When it matches a named entry, OCX resolves it to that entry's url.

toml
[registry]
default = "ghcr.io"

[registries.<name>]

Per-registry settings, keyed by a friendly name. Each entry configures one registry; [registry] default can then reference it by name rather than by hostname.

The plural form (registries, not registry) is deliberate: it mirrors Cargo's convention and avoids a TOML collision with the singular [registry] global-settings section.

url

Type: string

The actual registry hostname this entry resolves to. When [registry] default names this entry, OCX uses url as the effective default registry hostname.

toml
[registry]
default = "company"

[registries.company]
url = "registry.company.example"

[registries.ghcr]
url = "ghcr.io"

v1 scope

Only url is defined in v1. The [registries.<name>] table is reserved for per-registry settings — future fields (insecure, location rewrite, timeout, auth) will slot into the same entry without breaking existing configs. Unknown fields inside an entry are rejected (typo protection); unknown top-level sections are silently ignored (forward compatibility).

Environment Variable Override Table

This table shows which OCX environment variables map to config file fields. Variables not listed here have no config equivalent.

Environment VariableConfig EquivalentNotes
OCX_DEFAULT_REGISTRY[registry] defaultEnv var wins when both are set
OCX_HOMENoneDetermines where config is loaded from; cannot be in a config file
OCX_CONFIGNoneMeta-variable pointing at the config file itself
OCX_NO_CONFIGNoneKill switch; cannot be represented in a config file by definition
OCX_OFFLINENonePer-invocation mode, not a persistent setting
OCX_REMOTENonePer-invocation debugging mode, not a persistent setting
OCX_BINARY_PINNoneSubprocess-only: set automatically by ocx on every spawn so child ocx invocations pin to the same binary
OCX_INSECURE_REGISTRIESNone (deferred)Will move to a per-entry insecure field under [registries.<name>] once the flag is implemented; the env var remains the source of truth today
OCX_NO_UPDATE_CHECKNoneCI-only concern; env var is sufficient
OCX_NO_MODIFY_PATHNoneInstall-time concern; env var is sufficient

OCX_OFFLINE and OCX_REMOTE are intentionally absent from the config file. Both are per-invocation modes — a persistent offline = true would silently break ocx install on a fresh setup.

Error Reference

Literal sizes in the examples below reflect the current 64 KiB safety cap (MAX_CONFIG_SIZE in the loader source). Angle-bracket placeholders such as <SIZE> stand in for runtime values that depend on the offending file.

ErrorCauseResolution
error: config file not found: /path/to/file.toml (check --config or OCX_CONFIG)--config or OCX_CONFIG points to a non-existent fileCheck the path; unlike the three discovery tiers, explicit paths must exist. To disable an ambient OCX_CONFIG without unsetting it, set it to the empty string.
error: config file /path/to/file.toml exceeds maximum allowed size (<SIZE> bytes > 65536 bytes); OCX config files are typically under 1 KiB — did you point at the wrong fileA config file is larger than the 64 KiB safety capThe hint usually explains it — a --config flag or OCX_CONFIG env var pointed at a non-config file (e.g. an archive or binary).
error: invalid TOML at /path/to/file.toml: ...TOML syntax error in the config fileFix the TOML syntax error at the indicated location
error: failed to read config file /path/to/file.toml: ...The file exists but cannot be read — permission denied, the path is a directory, or another I/O failureCheck file permissions; --config and OCX_CONFIG must point to a regular, readable file.

Future Config Keys

Not yet implemented in v1

These sections are documented here so the format design is stable before they land. They do not exist in the current release.

Per-registry fields beyond url

The [registries.<name>] table is live in v1, but only url is defined. Future per-registry fields will slot in without breaking existing configs:

toml
# Future shape (not in v1 — only `url` is implemented today):
[registries.private]
url = "registry.company.example"
insecure = false                 # per-registry TLS opt-out
location = "mirror.company.example"  # URL rewrite / mirror

[patches] section

Infrastructure patch entries will live under [patches]. This section is reserved for the patches feature and is ignored by the v1 loader.

[clean] section

Retention policy configuration will live under [clean]. Deferred to the retention policy feature.

Project-level ocx.toml

A CWD-walk for a project-level ocx.toml is planned. The file name is deliberately different from config.toml so the data-directory tier and project tier are never confused. When it lands, it will sit between $OCX_HOME/config.toml and OCX_CONFIG in the precedence order.