OpenCode Configuration Options and Precedence Order: The Complete Guide
OpenCode merges configuration from seven distinct sources, with later sources overriding earlier ones: managed config directories (highest precedence), inline environment variables, .opencode directories, project config files, custom config paths, global user config, and remote well-known endpoints (lowest precedence).
OpenCode, the open-source AI coding assistant from anomalyco/opencode, uses a hierarchical configuration system to determine runtime behavior. Understanding OpenCode's configuration options and precedence order is essential for customizing the editor, managing enterprise deployments, and debugging environment-specific issues.
Configuration Precedence Order in OpenCode
The loading pipeline in packages/opencode/src/config/config.ts processes seven configuration sources sequentially, with each subsequent source merging into—and overriding—the previous accumulator. The comment at lines 71-78 documents this hierarchy explicitly.
The Seven Configuration Sources (Lowest to Highest Precedence)
- Remote well-known config (
/.well-known/opencode): Organization-wide defaults fetched from a remote server when an authentication token is present. - Global user config (
~/.config/opencode/*): Local global configuration files and remote org defaults merged together. - Custom config path (
OPENCODE_CONFIG): A specific file path provided via CLI flag or environment variable. - Project config (
opencode.jsonoropencode.jsonc): Discovered by walking up the directory tree from the current working directory, with closer files taking precedence. .opencodedirectories: Scanned in both the user's home directory (~/.opencode) and project trees, containing subdirectories foragents/,commands/,plugins/, and additional JSONC files.- Inline config (
OPENCODE_CONFIG_CONTENT): Raw JSON supplied directly via environment variable, parsed and merged immediately before managed config. - Managed config directory (
managedConfigDir): Enterprise-only path (typically/etc/opencodeon Linux) containing admin-controlled settings that override every other source.
Merge Behavior
The merge helper function defined at lines 56-66 in packages/opencode/src/config/config.ts handles the combination of configuration objects. For scalar values, later sources overwrite earlier ones. For array fields—such as plugin and instructions—the function concatenates arrays rather than replacing them, ensuring cumulative configuration from multiple layers.
OpenCode Configuration Options (The Info Schema)
All configuration options are defined and validated by the Info Zod schema in packages/opencode/src/config/config.ts. The schema supports dozens of optional fields organized into functional categories.
Core Application Settings
$schema: JSON Schema URI for validation.theme: UI theme name for the terminal interface.logLevel: Verbosity control (error,warn,info,debug).username: Custom display name overriding the system username.autoupdate: Update behavior (true,false,"notify").
Model and Provider Configuration
model/small_model: Default model identifiers inprovider/modelformat.default_agent: Primary agent name when none is specified.disabled_providers/enabled_providers: Provider whitelist/blacklist.provider: Per-provider configuration object containing API keys, timeouts, and model overrides.
Interface and Server Options
keybinds: Custom keyboard shortcuts mapping.tui: Terminal UI settings including scroll speed and diff style.server: HTTP server configuration (port,hostname,mdns,cors).
Extensions and Integrations
plugin: Array of plugin specifiers (npm packages orfile://URLs).skills: Paths or URLs to additional skill directories.mcp: Model Context Protocol server configurations.lsp: Language Server Protocol integration settings.formatter: Code formatting options.
Advanced and Experimental
instructions: Array of glob patterns or file paths containing extra system prompts.experimental: Feature flags for unstable capabilities (disable_paste_summary,batch_tool,openTelemetry).compaction: Context compaction settings (auto,prune,reserved).permission: Fine-grained tool permission matrix.snapshot: Boolean controlling filesystem snapshots before command execution.
Practical Configuration Examples
Loading Configuration at Runtime
import { Config } from "@opencode-ai/opencode";
async function showConfig() {
const { config } = await Config.state(); // triggers the loading pipeline
console.log("Effective OpenCode config:", config);
}
showConfig();
Overriding Settings via Environment Variables
// Highest precedence inline config
process.env.OPENCODE_CONFIG_CONTENT = JSON.stringify({
theme: "solarized-dark",
server: { port: 8080 },
});
await Config.state(); // config now contains the overridden values
Using a Custom Configuration File
// CLI flag: --config /path/to/custom.opencode.jsonc
import { Flag } from "@opencode-ai/flag";
Flag.OPENCODE_CONFIG = "/path/to/custom.opencode.jsonc";
await Config.state(); // merges after global config but before project config
Key Source Files
| File | Purpose | Link |
|---|---|---|
packages/opencode/src/config/config.ts |
Core configuration loading, merging logic, and Info schema definition. |
View source |
packages/opencode/src/config/markdown.ts |
Parses .md command and agent files consumed by the config loader. |
View source |
packages/opencode/src/util/filesystem.ts |
Helper utilities for locating config files by walking the directory tree. | View source |
packages/opencode/src/flag/flag.ts |
CLI flag definitions including OPENCODE_CONFIG and OPENCODE_CONFIG_CONTENT. |
View source |
packages/opencode/src/auth/index.ts |
Authentication token retrieval for remote well-known config fetching. | View source |
Summary
- OpenCode loads configuration from seven distinct sources, with later sources overriding earlier ones according to the precedence hierarchy documented in
packages/opencode/src/config/config.ts. - Managed config directories hold the highest precedence (enterprise deployments), while remote well-known endpoints provide the lowest precedence (organization defaults).
- The
mergehelper concatenates arrays (forpluginandinstructions) while overwriting scalars, ensuring cumulative configuration from multiple layers. - All options are validated against the
InfoZod schema, covering models, providers, UI settings, MCP servers, LSP integration, and experimental features.
Frequently Asked Questions
What is the highest priority configuration source in OpenCode?
The managed config directory (managedConfigDir, typically /etc/opencode on Linux) holds the highest precedence. This enterprise-only source is loaded last in the pipeline and overrides all other configuration layers, allowing administrators to enforce organization-wide policies that users cannot override.
How does OpenCode handle conflicting array values like plugins?
OpenCode uses a custom merge function defined at lines 56-66 in packages/opencode/src/config/config.ts that concatenates arrays rather than replacing them. This means if you define plugin entries in both your global user config and project config, all plugins from both sources are loaded, with later entries appended to the array.
Can I override OpenCode settings without creating a file?
Yes. You can use the OPENCODE_CONFIG_CONTENT environment variable to supply raw JSON configuration directly. This inline config has the second-highest precedence (after managed directories) and overrides any file-based settings. Alternatively, use the --config CLI flag to specify a custom file path.
Where does OpenCode look for project configuration files?
OpenCode searches for opencode.json or opencode.jsonc files by walking up the directory tree from the current working directory. It merges all discovered files, with configurations closer to the project root taking precedence over those found higher in the filesystem hierarchy. This logic is implemented in packages/opencode/src/util/filesystem.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →