Your code changed. Your local env should too.
local.env keeps a team's local development environment variables synchronized with the code changes that require them.
It connects GitHub pull requests with a local CLI, so a new environment requirement can be detected, resolved, and distributed without passing .env files around in Slack or DMs.
Self-hosted. Apache-2.0 licensed. Plaintext managed values stay on developer machines.
Website · Documentation · Releases
With cosign on PATH:
curl -fsSL https://www.local.env.best/install.sh | shThe installer detects macOS/Linux and amd64/arm64, verifies the signed release checksum manifest and archive digest, and installs to ~/.local/bin/localenv by default. See the CLI installation guide for verification details, version pinning, and custom install directories.
Adding a new environment variable is easy:
+ STRIPE_SECRET_KEY=Keeping everyone else's local environment up to date is usually not.
Someone mentions the new key in Slack. Someone sends the value over DM. A developer misses the message. Another joins the project two weeks later. Eventually someone pulls main and discovers that the code works — their local environment is just stale.
local.env moves that coordination back into the development workflow.
PR adds a new environment key
↓
local.env detects the requirement
↓
GitHub readiness check reports it missing
↓
developer runs `localenv resolve --pr 42`
↓
value is encrypted on the developer machine
↓
readiness check passes
↓
merge
↓
teammates run `localenv sync`
GitHub sees the key name and its readiness state.
It never receives the managed plaintext value.
A repository opts into local.env with a small committed localenv.yaml file:
version: 1
files:
- schema: .env.example
target: .env.localThe schema declares which keys developers need:
DATABASE_URL=
STRIPE_SECRET_KEY=
REDIS_URL=The schema belongs in Git.
The developer's actual values do not.
Monorepos can declare multiple schema/target pairs:
version: 1
files:
- schema: apps/web/.env.example
target: apps/web/.env.local
- schema: apps/api/.env.example
target: apps/api/.env.localSign in to your team's local.env instance:
localenv login https://env.example.comA repository is initialized once by an authorized developer:
localenv repo initWhen a pull request introduces a new requirement:
localenv resolve --pr 42After the change merges:
git pull
localenv syncWant to inspect changes without touching your local file?
localenv diff
localenv sync --dry-runDon't want managed values written to a dotenv file at all?
localenv run -- npm run devThe CLI decrypts the managed values in memory and passes them directly to the child process environment.
- Keeps local-development environment requirements alongside the codebase.
- Detects new environment keys introduced by pull requests.
- Reports environment readiness through GitHub.
- Encrypts managed values locally before upload.
- Synchronizes only the managed section of local dotenv files.
- Supports runtime injection without writing managed values to disk.
- Manages repository access through authorized devices.
- Supports repository-key rotation after device revocation.
- Provides a self-hosted, metadata-only dashboard for repositories, devices, and audit events.
local.env is designed so the coordination server does not need managed plaintext secrets.
- Managed values are encrypted and decrypted by the CLI.
- Repository encryption keys are generated on developer machines.
- The server stores ciphertext and device-wrapped repository keys.
- GitHub receives key names and readiness metadata, not secret values.
- The dashboard never accepts or displays managed secret values.
A compromised authorized developer machine is outside this boundary: a device that has already received a secret cannot be made to forget it.
Read the security model and threat model for the complete design.
local.env is intentionally narrow.
It is not a production secret manager, CI secret store, cloud vault, password manager, or browser-based secret editor.
Use your existing infrastructure for production and deployment credentials.
local.env focuses on one problem:
keeping local development environments synchronized with the code changes that introduce new requirements.
Each team runs its own local.env instance and connects an organization-owned GitHub App.
The service requires:
- an HTTPS endpoint,
- persistent storage,
- a GitHub organization,
- the bootstrap GitHub authentication configuration,
- and the local.env server.
Start with the self-hosting guide.
If your organization already runs an instance, follow the developer onboarding guide.
The main commands are:
localenv login
localenv status
localenv repo init
localenv resolve
localenv set
localenv import
localenv sync
localenv diff
localenv run
localenv doctor
localenv devices
localenv keys rotate
See the CLI reference for details.
Contributions are welcome.
Please read CONTRIBUTING.md before opening a pull request. Security-sensitive issues should follow SECURITY.md instead of being reported publicly.
Apache License 2.0.