---
url: https://findutils.com/guides/env-merge
title: "Combine .env and .env.local Into One File, With Clear Conflict Rules"
description: "Flatten layered dotenv files into one .env for a host, a container or a teammate. Pick which file wins on conflicts, then check the result. Runs in your browser."
category: developer
content_type: guide
guide_type: subtopic
cluster: configuration
locale: en
read_time: 7
status: published
author: "olgunozoktas"
published_at: 2026-09-25T12:00:00Z
excerpt: "Frameworks read .env, .env.local and a mode file in a fixed order, but a hosting panel or a container often takes exactly one file. Flattening the layers by hand means copying keys and hoping the right value won. A merge with an explicit conflict rule does it in one pass."
tag_ids: ["dotenv", "env", "configuration", "developer-tools", "secrets"]
tags: ["Dotenv", "Env", "Configuration", "Developer Tools", "Secrets"]
primary_keyword: "combine .env and .env.local"
secondary_keywords: ["merge env files", "merge dotenv files", "env file override order", "flatten env files into one", "add new keys from .env.example"]
tool_tag: "env-merge"
related_tool: "env-merge"
related_tools: ["env-merge", "env-diff", "env-linter", "env-json-converter", "env-yaml-converter"]
og_image: "/images/content/guides/env-merge-cover-20260925.webp"
image_alt: "A pale teal acrylic sheet and a pale amber sheet with blank coloured paper dots, laid so the amber sheet overlaps the teal one on a white table."
updated_at: "2026-09-25T12:00:00Z"
---

To combine `.env` and `.env.local` into one file, merge them with `.env` as the base and `.env.local` as the overlay, and let the overlay win when a key has two values. That is the order most frameworks read them in. FindUtils [Env Merge](/developers/env-merge/) does this in your browser: every key from both files is kept, each conflict is listed with the value that won, and you download one `merged.env`. The files are not uploaded.

This guide covers when you need a single file, how frameworks decide which value wins, which conflict rule to pick, and how to merge more than two layers.

## When You Need One File Instead of Several

A framework running on your machine reads its layers itself. Other places often take exactly one file or one block of variables:

- **A hosting control panel** with a single environment editor or a single file upload.
- **A container** started with one env file.
- **A teammate** who needs your working setup without your folder of overrides.
- **A secrets manager import**, which usually takes one set of key-value pairs (convert it with [Env JSON Converter](/developers/env-json-converter/) if the import wants JSON).

Flattening the layers by hand is where keys get dropped or the wrong value survives. A merge with a stated rule makes the result reproducible.

## How Frameworks Decide Which Value Wins

Each loader has its own order, and the merge should copy the one your app uses:

| Loader | Documented rule |
|---|---|
| Next.js | Looks in `process.env`, `.env.$(NODE_ENV).local`, `.env.local`, `.env.$(NODE_ENV)`, `.env`, and [stops at the first one that defines the variable](https://nextjs.org/docs/app/guides/environment-variables) |
| Vite | A mode file such as `.env.production` [takes higher priority than a generic one](https://vite.dev/guide/env-and-mode); variables already in the environment when Vite starts are never overwritten |
| dotenv | [Never modifies a variable that is already set](https://github.com/motdotla/dotenv) unless you pass `override: true` |

The common thread: the more specific file wins over the generic one, and variables set by the host win over every file. Env Merge only sees the two files you give it, so a variable the host sets directly is not part of the result.

## Which Conflict Rule to Pick

A conflict is a key present in both files with different values. The **On conflict** setting decides it:

| Rule | What happens | Use it when |
|---|---|---|
| Overlay wins (default) | The overlay value replaces the base value | Flattening `.env` + `.env.local`, or `.env` + `.env.production`, the way frameworks layer them |
| Base wins | The base value is kept; the overlay only adds keys the base lacks | Adding new keys from `.env.example` to your `.env` without touching your values |
| Overlay wins unless its value is empty | The overlay value is used, except when it is empty | An overlay with blank placeholders that should not wipe real values |
| Stop and list the conflicts | Nothing is merged; the conflicting keys are listed | Checking two files that should agree before you trust either |

Keys that exist in only one file are always kept, whatever the rule. Keys with the same value on both sides are counted as identical and written once.

## How to Merge Two Files

### Step 1: Paste or drop the base and the overlay

Open [Env Merge](/developers/env-merge/). Put the lower-priority file in Base (A), for example `.env`, and the higher-priority file in Overlay (B), for example `.env.local`.

### Step 2: Choose the rule and the output format

Pick the conflict rule. **Sort keys A to Z** writes the keys alphabetically instead of in base order. **Write export before each line** prefixes every line with `export `, for a file a shell will source.

### Step 3: Read the conflict table

Each conflict shows the key, the base value, the overlay value and the winner. **Hide secret-looking values** masks values in that table for keys that look like secrets, and the password inside connection URLs, which is useful before sharing your screen. The downloaded file always holds the real values.

### Step 4: Download the merged file

Download `merged.env` or copy the output. The summary gives the key count, how many keys came from the base, how many were added from the overlay, and how many conflicts were resolved.

## Merging More Than Two Layers

Env Merge takes two files at a time. For three or four layers, merge from the lowest priority up and use each result as the next base, with Overlay wins:

1. Base `.env`, overlay `.env.production`: download the result.
2. Base: that result, overlay `.env.local`.
3. Base: that result, overlay `.env.production.local`.

With Overlay wins at every step, a key ends up with the value from the highest-priority file that defines it, which matches the Next.js lookup order above for a production build.

## What the Merged File Looks Like

- **Key order.** Base keys come first in the base file's order, then keys that exist only in the overlay, in the overlay's order, unless you sort.
- **Quoting.** A value is written bare when it can be. It is double-quoted, with escapes such as `\n` and `\"`, only when it holds whitespace, `#`, a quote character, a backslash or a line break, or has leading or trailing spaces.
- **Comments.** Comments and blank lines are not carried over, and a note says so when either file had comments. Keep the originals if the comments matter.
- **Duplicates.** A key written twice inside one file keeps its last value, and a warning gives the line numbers.
- **References.** `$VAR` and `${VAR}` are copied as text. Next.js expands `$VARIABLE` references when it loads a file; Env Merge does not, so the merged file keeps the reference for the loader to resolve.

A base file with no keys stops the merge with a message. An empty overlay simply gives you the base back, re-written in the output format.

## Check the Result Before You Use It

Compare the base with `merged.env` in [Env Diff](/developers/env-diff/). Every added and changed key in that report came from the overlay, so it is a quick way to confirm that the merge did what you meant and nothing else.

## Common Mistakes

**Swapping base and overlay.** With Overlay wins, the file in the Overlay pane wins. Put `.env.local` in Base and your local overrides lose.

**Using Overlay wins to add template keys.** An example file often holds placeholder values like `changeme`. Merged as the overlay with Overlay wins, those placeholders replace your real values. Use Base wins for that job.

**Committing the merged file.** It holds every secret from both layers. The dotenv README and the Next.js documentation both advise against committing `.env` files; treat `merged.env` the same way.

## Tools Used in This Guide

| Tool | Use |
|---|---|
| [Env Merge](/developers/env-merge/) | Combine a base .env and an overlay with a conflict rule |
| [Env Diff](/developers/env-diff/) | Compare the base and the merged file key by key |
| [Env Linter](/developers/env-linter/) | Check each file for duplicate keys and quoting problems before merging |
| [Env JSON Converter](/developers/env-json-converter/) | Turn the merged file into JSON for an import form |
| [Env YAML Converter](/developers/env-yaml-converter/) | Turn the merged file into YAML for a config file |

## FAQ

### Does .env.local override .env?

In Next.js, yes: `.env.local` is checked before `.env`, and the first file that defines a variable wins. To reproduce that in one file, merge with `.env` as the base, `.env.local` as the overlay and Overlay wins.

### How do I add new keys from .env.example without losing my values?

Merge with your `.env` as the base, `.env.example` as the overlay and Base wins. Keys only in the example are added with the example's values, and every key you already have keeps your value.

### Can I merge three .env files at once?

Not in one step. Merge the two lowest-priority files, then use the result as the base for the next file, keeping Overlay wins, until every layer is in.

### Are comments kept in the merged file?

No. Only KEY=value lines are written, and a note appears when either input had comments.

## Next Steps

Flatten your layers with [Env Merge](/developers/env-merge/), then confirm the result against the base with [Env Diff](/developers/env-diff/).
