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

> Source: <https://dev.to/uehara/stop-editing-the-same-value-in-every-env-one-dotvault-project-for-every-environment-one-common-2fab>
> Published: 2026-10-30 12:11:44+00:00

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` in`project-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](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](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](https://dev.to/uehara/the-18-products-earthlink-network-builds-in-house-hb1)

For more about the company and each product, visit [www.eln.ne.jp](https://www.eln.ne.jp).
