[FEATURE]: Auto-load .env files in scoped directories for {env:VAR} substitution #7487

Open
opened 2026-02-16 18:07:20 -05:00 by yindo · 3 comments
Owner

Originally created by @mcking-07 on GitHub (Jan 24, 2026).

Originally assigned to: @thdxr on GitHub.

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem

When trying to share a reproducible OpenCode setup within my team, configs quickly become unmanageable due to hardcoded credentials. The {env:VAR} syntax exists and is perfect for this use case, but there's no built-in way to populate those environment variables when running opencode.

Currently, populating variables requires manual shell exports or external tools like direnv.

This friction makes {env:VAR} syntax largely unused in practice, and configs remain filled with hardcoded secrets that can't be committed to version control systems like git.

Proposed Solution

Auto-load .env files from the same directory as opencode.json:

project/
└── .opencode/
    ├── opencode.json         # Git-tracked with {env:VAR} references
    ├── .env.example          # Git-tracked template
    └── .env                  # Git-ignored, auto-loaded

Configuration Example

.env:

SOME_MCP_API_KEY="your-key-here"
ANTHROPIC_API_KEY="your-key-here"

opencode.json:

{
  "mcp": {
    "some-server": {
      "type": "remote",
      "url": "https://api.example.com?key={env:SOME_MCP_API_KEY}"
    }
  },
  "username": "{env:USER}"
}

Implementation

Add support for auto-loading .env files from the same directory as the loaded opencode.json config. Two locations should be supported:

  1. Global: ~/.config/opencode/.env (personal defaults, respects $OPENCODE_CONFIG_DIR)
  2. Project: ./.opencode/.env (project-specific overrides)

Loading Precedence

  1. Global .env (~/.config/opencode/.env)
  2. Project .env (./.opencode/.env) - overrides global
  3. Process Environment - overrides both
  4. Config parsing with {env:VAR} substitution

Opt-In vs Opt-Out

Option A: Opt-In (Recommended)

  • Requires OPENCODE_AUTO_LOAD_ENV=true
  • Explicit, zero surprise for existing users

Option B: Opt-Out

  • Enabled by default when .env exists
  • Requires OPENCODE_DISABLE_AUTO_LOAD_ENV=true to disable

Recommendation: Opt-in. Matches OpenCode's transparency principles while still being simple to enable once.

Code Location

Hook into Config.state() in src/config/config.ts after config discovery, before variable substitution:

  1. Check enablement flag
  2. Load global .env from ~/.config/opencode/.env (respects $OPENCODE_CONFIG_DIR)
  3. Load project .env from directory containing opencode.json
  4. Log (debug): Loading environment from /path/to/.env
  5. Make variables available for {env:VAR} substitution

Benefits

  • Teams: Share complete setups without secrets
  • Plugins: Document required variables via .env.example
  • Security: Credentials stay local, configs in git
  • Reproducibility: Clone and run with minimal setup
  • Scope-aware: Only loads from .opencode/ directories, not project root

Questions for Community

  1. Opt-in (OPENCODE_AUTO_LOAD_ENV=true) or opt-out (default enabled)?
  2. Any security concerns with auto-loading .env files?
  3. Alternative implementation suggestions?

I'm open to feedback and ready to implement whichever approach is preferred based on the community consensus.

Originally created by @mcking-07 on GitHub (Jan 24, 2026). Originally assigned to: @thdxr on GitHub. ### Feature hasn't been suggested before. - [x] I have verified this feature I'm about to request hasn't been suggested before. ### Describe the enhancement you want to request ## Problem When trying to share a reproducible OpenCode setup within my team, configs quickly become unmanageable due to hardcoded credentials. The `{env:VAR}` syntax exists and is perfect for this use case, but there's no built-in way to populate those environment variables when running `opencode`. Currently, populating variables requires manual shell exports or external tools like direnv. This friction makes `{env:VAR}` syntax largely unused in practice, and configs remain filled with hardcoded secrets that can't be committed to version control systems like git. ## Proposed Solution Auto-load `.env` files from the same directory as `opencode.json`: ```markdown project/ └── .opencode/ ├── opencode.json # Git-tracked with {env:VAR} references ├── .env.example # Git-tracked template └── .env # Git-ignored, auto-loaded ``` ### Configuration Example `.env`: ```bash SOME_MCP_API_KEY="your-key-here" ANTHROPIC_API_KEY="your-key-here" ``` `opencode.json`: ```json { "mcp": { "some-server": { "type": "remote", "url": "https://api.example.com?key={env:SOME_MCP_API_KEY}" } }, "username": "{env:USER}" } ``` ## Implementation Add support for auto-loading `.env` files from the same directory as the loaded `opencode.json` config. Two locations should be supported: 1. **Global**: `~/.config/opencode/.env` (personal defaults, respects `$OPENCODE_CONFIG_DIR`) 2. **Project**: `./.opencode/.env` (project-specific overrides) ### Loading Precedence 1. Global .env (~/.config/opencode/.env) 2. Project .env (./.opencode/.env) - overrides global 3. Process Environment - overrides both 4. Config parsing with {env:VAR} substitution ### Opt-In vs Opt-Out #### Option A: Opt-In (Recommended) - Requires `OPENCODE_AUTO_LOAD_ENV=true` - Explicit, zero surprise for existing users #### Option B: Opt-Out - Enabled by default when `.env` exists - Requires `OPENCODE_DISABLE_AUTO_LOAD_ENV=true` to disable **Recommendation:** Opt-in. Matches OpenCode's transparency principles while still being simple to enable once. ### Code Location Hook into `Config.state()` in `src/config/config.ts` after config discovery, before variable substitution: 1. Check enablement flag 2. Load global `.env` from `~/.config/opencode/.env` (respects `$OPENCODE_CONFIG_DIR`) 3. Load project `.env` from directory containing `opencode.json` 4. Log (debug): `Loading environment from /path/to/.env` 5. Make variables available for `{env:VAR}` substitution ## Benefits - **Teams:** Share complete setups without secrets - **Plugins:** Document required variables via `.env.example` - **Security:** Credentials stay local, configs in git - **Reproducibility:** Clone and run with minimal setup - **Scope-aware:** Only loads from `.opencode/` directories, not project root ## Questions for Community 1. Opt-in (`OPENCODE_AUTO_LOAD_ENV=true`) or opt-out (default enabled)? 2. Any security concerns with auto-loading `.env` files? 3. Alternative implementation suggestions? I'm open to feedback and ready to implement whichever approach is preferred based on the community consensus.
yindo added the discussion label 2026-02-16 18:07:20 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 24, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #231: add ability to load secrets from external command or environment variables in the config file (earliest related feature request from 2020)
  • #5054: {env:MY_VAR} support in agent yaml (shows demand for env var substitution in configs)
  • #5299: {env:...} variable substitution inconsistently fails for specific MCP server URLs (existing issue with {env:VAR} syntax)
  • #9334: How to make OpenCode load environment variables from a file when executing commands in skills (user asking for .env file loading)

Feel free to ignore if your implementation differs from these existing proposals.

@github-actions[bot] commented on GitHub (Jan 24, 2026): This issue might be a duplicate of existing issues. Please check: - #231: add ability to load secrets from external command or environment variables in the config file (earliest related feature request from 2020) - #5054: {env:MY_VAR} support in agent yaml (shows demand for env var substitution in configs) - #5299: {env:...} variable substitution inconsistently fails for specific MCP server URLs (existing issue with {env:VAR} syntax) - #9334: How to make OpenCode load environment variables from a file when executing commands in skills (user asking for .env file loading) Feel free to ignore if your implementation differs from these existing proposals.
Author
Owner

@vpcano commented on GitHub (Feb 14, 2026):

I think desktop/web app would benefit from this, because on the TUI you can at least source a .env file manually or use dotenv, but on the desktop application there is no way to load env vars from a project.

@vpcano commented on GitHub (Feb 14, 2026): I think desktop/web app would benefit from this, because on the TUI you can at least source a .env file manually or use dotenv, but on the desktop application there is no way to load env vars from a project.
Author
Owner

@mcking-07 commented on GitHub (Feb 15, 2026):

@vpcano Good point on the desktop gap. This is straightforward to implement since {env:VAR} substitution already exists, just need to load .env files before config parsing. Given the 4 related issues flagged, seems like there's clear demand for this. Thoughts on the opt-in vs opt-out approach?

@mcking-07 commented on GitHub (Feb 15, 2026): @vpcano Good point on the desktop gap. This is straightforward to implement since `{env:VAR}` substitution already exists, just need to load `.env` files before config parsing. Given the 4 related issues flagged, seems like there's clear demand for this. Thoughts on the opt-in vs opt-out approach?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#7487