cd /news/developer-tools/stop-editing-the-same-value-in-every… · home › topics › developer-tools › article
[ARTICLE · art-160895] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Stop editing the same value in every .env: one dotvault project for every environment, one Common layer

A developer building the dotvault secrets-management tool introduced a Common (_shared) layer that merges into every environment's pull, so a value shared across development, staging and production is stored and edited once rather than duplicated in each .env file. The tool also adds an environment comparison drawer with per-key and bulk copy actions, and a "Promote to Common" action that moves an existing environment key into the shared layer. Environment-specific keys of the same name override Common, and copied values do not propagate after the copy.

by read8 min views1 publishedOct 30, 2026

This is part 3 of the series "dotvault, Start to Finish: One Command from Your Laptop to CI, Your Team, and Your AI Agents." dotvault will be released free of charge when this series ends.

In this part, a key disappears from development's key list, and yet the next development pull still writes it into .env. Nothing went wrong. That key now lives in Common, the layer dotvault merges into the pull of every environment, and it is stored there exactly once.

That is the point of this part. If you keep a separate .env for development, staging and production, every value that is the same everywhere is written once per environment, and changing it means editing it in every file. Miss one, and that environment runs on the old value. In dotvault, those separate files become the development, staging and production environments of one project, managed in one place in the console. A value shared by every environment goes into Common once, so you change it once. When one environment needs something different, a key of the same name in that environment wins over Common.

This is part 3 of 12, continuing with the demo-app project from part 2.

.env files become environments of one project: development, staging and production.preview)._shared), once.-E, then DOTVAULT_ENV (or APP_ENV if that is unset), then defaultEnv in project-config.json. demo-app with three keys in development and a successful dotvault pull. You can follow this part without having read it.# BEGIN: dotvault (managed by dotvault). I checked that environment selection ( echo $? line.NAME=value line in In dotvault, the .env you kept per environment becomes an environment inside one project. The demo-app project from part 2 has three: development, staging and production. They are dotvault's standard environments and cannot be removed. The Keys tab has an environment switch above the list; pick an environment and you see its keys. Every environment's values are read and edited from this one screen.

This screen already shows preview, which is added later in this part, and Common (_shared), where values shared by every environment go. We build up to it.

With every environment in one project, you can put two of them side by side. After part 2, the three keys exist only in development. Whether staging or production need the same keys is not visible until you compare. "⇄ Compare envs…" on the Keys tab opens a drawer with two environment selectors.

"Only in development" lists the keys the other side lacks. The "Copy to production" button on a row copies that one key; "Copy all to production" copies every key in the list. For this article I first copied all three to staging. Comparing staging with development afterwards shows a single line.

These two screens were taken after section 3 moved API_BASE_URL to Common. Keys in Common are not part of the comparison, so only two keys (DATABASE_URL and SMTP_PASSWORD) appear.

What gets copied is the key name and the value at that moment. Changing the development value later does not propagate to staging. That is the point of environments, so it is intended. A key that should stay identical everywhere is not copied around; it goes into Common, next.

In this demo, API_BASE_URL holds the same value in every environment. In a real project, this is the place for keys like a third-party service's public key or the address your app sends email from. Writing it into each environment means changing it in each environment. Common (shown as Common (_shared) in the console, _shared on the CLI) is the layer for that. A key placed in Common is written out with every environment's pull. There is one value, so a change is one edit.

A key already sitting in an environment moves into Common with "⬆ Promote to Common (_shared)". Select the key and press it; a confirmation appears.

As the dialog says, development's value becomes the Common value. The same-named key leaves the three standard environments (development, staging, production) and lives in Common alone. Keys in environments you added yourself stay, and they still take priority over Common. After confirming, development and Common look like this.

That is the key that vanished from development's list at the top of this article. The pulled .env still contains it, now as the Common value (checked in section 5).

When one environment needs a different value, add a key of the same name in that environment. The environment's value takes precedence over Common. Section 5 checks that too, with a different value in preview.

Common gathers the values shared by the environments of one project. Values shared across projects come in part 6, with Global Keys.

When the standard three are not enough, add another environment to the same project; it sits next to the others on the same screens. Add it under Environments on the Settings tab. Names are lowercase letters, digits and hyphens, starting with a letter, at most 32 characters. "Copy keys from an existing env" copies that environment's keys into the new one right away. I added preview, copied from development.

Environments you added get Rename and Delete. The standard three and _shared do not. Rename opens a dialog for the new name and notes that every key and permission referencing the old name is rewritten.

An environment that still holds keys or permissions cannot be deleted. Pressing Delete on preview with keys in it, and confirming, shows "This environment still has keys or permissions. Remove those first." and nothing is removed. To delete it, first remove its keys and any permissions granted on that environment.

After this I added API_BASE_URL to preview with a different value (https://preview.example.com/v1), to see which wins, Common or the environment.

The values kept in one place in the console come out on the terminal by naming the environment. dotvault list demo-app prints the key count per environment, including the preview you added.

production shows 1 although nothing was put there. That is Common being counted: API_BASE_URL in Common is merged into every environment.

-E (--env) selects the environment for a pull. Without it, and without the environment variables below, defaultEnv from project-config.json applies (development, as written by init in part 2).

dotvault pull
dotvault pull -E preview
dotvault pull -E production

Three things to notice.

API_BASE_URL. env=…. Before starting work, pull again for the environment you need. DOTVAULT_ENV selects the environment too, for cases like CI or npm scripts where you want to switch without editing the command. When both are present, -E wins. If DOTVAULT_ENV is unset, the CLI also reads APP_ENV as the environment. So if your app already uses APP_ENV for its own settings, a plain pull with neither -E nor DOTVAULT_ENV gets that environment, not defaultEnv. DOTVAULT_ENV is the reliable way to pick the dotvault environment.

So the order is -E, then DOTVAULT_ENV (or APP_ENV), then defaultEnv. defaultEnv applies only when -E and both variables are absent. The same screen ends with a second dotvault init: in a folder that already has project-config.json it stops instead of overwriting, and --force is the way to start over.

How Written as Fits
Command flag dotvault pull -E staging A quick look at another environment
Environment variable DOTVAULT_ENV=staging dotvault pull CI and start scripts, switching without changing the command
Config file defaultEnv inproject-config.json The folder's everyday environment; init writes development

defaultEnv takes one of development, staging or production. Pick an environment you added yourself, such as preview, with -E (or DOTVAULT_ENV) each time.

A project that holds all your environments is also put away as a whole. The Danger zone sits at the bottom of the Settings tab. Archive this project asks for confirmation and then removes the project from the console's list. Archiving is reversible. Deleting is only possible after archiving.

Set the list filter to "Archived only" and the archived project appears with Unarchive and Delete… buttons.

Delete… opens a dialog that asks you to type the project name. Delete permanently stays disabled until the name matches. What goes is not only the current values but the whole version history covered in part 4.

This screen was taken on a throwaway project, scratch-app, so that demo-app survives. After Delete permanently, the project is gone even under "All (incl. archived)". demo-app was unarchived and continues into part 4.

Archiving and deleting a project are done in the console. On the CLI, dotvault project offers create and list.

The .env you used to keep per environment becomes an environment of one dotvault project, managed in one place in the console. A value every environment shares goes into Common once and reaches every pull, so you never edit the same value in two places.

Part 4: "Every value keeps every version: writing, pulling and rolling back keys." Keys from both the console and the CLI, reading values out, and restoring an earlier version from the version list, one screen at a time.

dotvault stores the secrets in your .env and config files server-side and hands them to any authorised developer, CI job or AI agent with a single command (https://dotvault.io). It will be released free of charge when this series ends, and the steps in these articles are the steps you will use on day one.

If you find this useful, please like and follow.

Our products are listed at https://www.eln.ne.jp/products

EarthLink Network builds its own products to run the whole company on AI — each one born from a need along the way. See the full index of what we build:

→ The 18 products EarthLink Network builds in-house

For more about the company and each product, visit www.eln.ne.jp.

── more in #developer-tools 4 stories · sorted by recency
── more on @dotvault 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/stop-editing-the-sam…] indexed:0 read:8min 2026-10-30 · —