This is the missing dotenv bridge for AI-powered coding:
- Automatic environment injection - Loads
.envfiles before AI-triggered bash commands and interactive terminals - Multi-environment support - Follows dotenv-flow convention for
.env.development,.env.production.local, etc. - Encrypted secrets - Supports encrypted values using dotenvx
- Variable expansion - Reference other variables:
DATABASE_URL=postgres://${USER}@localhost - Safe merging - Doesn't override existing environment variables
Opencode only loads .env for bash invocations.
But if you use anything more than a single .env file, your scripts will likely raise an new Error("Cannot find API_KEY"). Your helpful AI agents will eagerly peak at your secrets files to debug the code.
Loading env variables automatically in bash scripts keeps those errors away and your AI agents from the temptation to peak.
Add the plugin to your opencode.json config:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@tianhuil/opencode-dotenv"]
}OpenCode automatically installs npm plugins using Bun at startup. Packages are cached in ~/.cache/opencode/node_modules/. No manual install step is needed.
Create .env files in your project root:
# Global defaults
echo "APP_NAME=MyApp" > .env
echo "DATABASE_HOST=localhost" >> .env
# Development overrides
echo "DEBUG=true" > .env.development
echo "LOG_LEVEL=debug" >> .env.development
# Production overrides
echo "LOG_LEVEL=warn" > .env.production
echo "API_URL=https://api.example.com" >> .env.productionThe plugin reads the NODE_ENV environment variable to determine which files to load (defaults to development if not set):
| NODE_ENV | Files loaded (in priority order) |
|---|---|
development |
.env.development.local, .env.development, .env.local, .env |
production |
.env.production.local, .env.production, .env.local, .env |
test |
.env.test.local, .env.test, .env.local, .env |
| not set | Defaults to development |
Dotenvx can encrypt secrets directly in your .env files, so encrypted values are safe to commit and only decrypted at runtime with a private key:
# Install dotenvx CLI
bun install -g @dotenvx/dotenvx
# Generate encryption keys
dotenvx encrypt
# Set encrypted value
dotenvx set API_KEY "my-secret-key"Create .env.keys with your private keys:
DOTENV_PRIVATE_KEY="your-private-key-here"
DOTENV_PRIVATE_KEY_PRODUCTION="your-production-key"Important: Add .env.keys to .gitignore - never commit private keys.
When NODE_ENV=development:
1. .env.development.local (highest priority - never commit)
2. .env.development (dev defaults - safe to commit)
3. .env.local (local overrides - never commit)
4. .env (global defaults - safe to commit)
# ✅ Safe to commit (no secrets)
.env
.env.development
.env.production
.env.test
# ❌ Never commit (contains secrets)
.env.keys
.env.local
.env.*.localEnvironment variables not loading:
- Check
.envfiles exist in project root - Verify the plugin is listed in your
opencode.json
Wrong environment loaded:
- Check
NODE_ENV:echo $NODE_ENV - Verify file names:
.env.productionnot.env.prod
Encrypted values not decrypting:
- Ensure
.env.keysexists orDOTENV_PRIVATE_KEYis set - Check public/private key pair match
This section is for contributors working on the plugin itself. After cloning the repo, you can load the plugin locally instead of installing from npm.
After cloning, the plugin files are already in place. OpenCode will automatically load from .opencode/plugins/load-dotenv.ts. Restart OpenCode to pick up the plugin.
To use your local copy across all projects:
# Copy plugin to global plugins directory
mkdir -p ~/.config/opencode/plugins
cp .opencode/plugins/load-dotenv.ts ~/.config/opencode/plugins/
# Copy dependencies package.json
mkdir -p ~/.config/opencode
cp .opencode/package.json ~/.config/opencode/package.jsonopencode-dotenv/
├── src/
│ └── load-dotenv.ts # Main implementation
├── .opencode/
│ ├── package.json # Plugin dependencies
│ └── plugins/
│ └── load-dotenv.ts # Shim (loads plugin)
├── test/
│ ├── load-dotenv.test.ts # Unit tests
│ ├── e2e-cli.test.ts # E2E tests
│ └── fixtures/
│ ├── env-loading/ # Unit test fixtures
│ ├── encrypted-env/ # Encryption test fixtures
│ └── e2e/ # E2E test workspace
└── notes/
└── opencode-dotenv-plugin.md # Implementation docs
- Edit
src/load-dotenv.ts - Run tests:
bun test - Restart OpenCode
The shim in .opencode/plugins/load-dotenv.ts automatically reloads changes.
bun test test/load-dotenv.test.ts# Requires OpenCode CLI to be installed
bun test test/e2e-cli.test.tsbun testEnvironment variables not loading (local plugin):
- Check
.envfiles exist in project root - Verify plugin is in
.opencode/plugins/ - Run
bun installin.opencode/to install dependencies
This section is for maintainers publishing new versions to npm.
# 1. Install dependencies
bun install
# 2. Login to npm
npm login
# 3. Publish using np (automatically prompts for version bump)
bunx np --any-branchIf you prefer manual version control:
# Bump version (patch, minor, or major)
npm version patch
# Publish to npm
npm publish --access public