Skip to main content

align-dotenv

Keep local dotenv files aligned with their templates without losing local values.

The template controls structure and known variables. Your local file controls existing values and whether each variable is active or commented out. Unknown local variables are kept by default. Unsupported local syntax causes a safe failure, not data loss.

Install

Packages: npm · PyPI.

align-dotenv is available for both Python and Node.js development workflows. Both distributions expose the same CLI behavior. The npm package is intended as a development-time CLI; a stable JavaScript library API is not currently promised.

Node.js / npm

Node.js 22+ is supported.

npm install --save-dev align-dotenv

Run it directly:

npx align-dotenv
npx align-dotenv --check

Or add project scripts:

{
  "scripts": {
    "env:align": "align-dotenv",
    "env:check": "align-dotenv --check"
  }
}

The Node.js release is tested on Linux/Ubuntu (including WSL) and Windows with Node.js 22 and 24. macOS is not currently part of the tested release matrix, but installation is not blocked.

Python

Python 3.10–3.14 is supported.

uv tool install align-dotenv
# or
pipx install align-dotenv
# or
python -m pip install align-dotenv

Use

Explicit single-file mode

align-dotenv .env --template .env.example
align-dotenv .env --template .env.example --check
align-dotenv .env --template .env.example --unknown keep    # default
align-dotenv .env --template .env.example --unknown remove  # explicitly drop unknown keys
align-dotenv .env --template .env.example --unknown error   # fail, listing key names only

Project mode

Run without a target or template from the project root:

align-dotenv
align-dotenv --check
align-dotenv --unknown keep    # default
align-dotenv --unknown remove
align-dotenv --unknown error

Project mode recursively discovers .env*.example and .env*.template files and removes the suffix to find the corresponding local target. For example:

project/
├── .env                    ← .env.example
├── .env.example
└── apps/api/
    ├── .env.development    ← .env.development.template
    └── .env.development.template

Only existing targets are aligned; templates with missing targets are skipped and reported, never used to create targets. If two templates map to the same target (such as .env.example and .env.template), the command fails without writing.

Discovery is sorted by target path and skips .git, node_modules, .venv, venv, and __pycache__ directories, as well as directory symlinks.

Project mode validates and reconciles every pair in memory before writing any target. An invalid pair or --unknown error failure prevents all writes. After a successful preflight, changed files are replaced atomically one at a time; this is not a cross-file transaction. Unchanged files are not rewritten.

--check performs the same full preflight without writing:

  • exit 0: everything is aligned
  • exit 1: at least one target needs alignment
  • exit 2: invalid invocation, input, or project state

Reconciliation

Given .env.example:

# Required setting
REQUIRED=template

# OPTIONAL=template

and a local .env:

OPTIONAL='local choice'
REQUIRED=local

alignment produces:

# Required setting
REQUIRED=local

OPTIONAL='local choice'

The template keeps control of layout while existing local values and active/commented state are preserved.

Syntax and safety

Understand it, preserve it, or refuse to modify it.

Supported assignments are:

  • KEY=value
  • export KEY=value
  • # KEY=value
  • # export KEY=value

Keys must match [A-Za-z_][A-Za-z0-9_]*. Values are preserved as raw text; align-dotenv is intentionally not a full shell or dotenv interpreter.

Unsupported meaningful local content, such as shell directives, line continuations, or unclosed quoted values, stops the operation without modifying the file. Errors report safe metadata such as line numbers or unknown key names, not dotenv values.

The existing target must be a regular file, not a symlink or the template itself. Known lines follow the template's line endings and final newline. Unknown assignments kept by default retain their original representation. Changes are replaced atomically within the target directory, mode bits are preserved where meaningful, and already aligned files are not rewritten.

Development

Run the Python and Node.js suites from the repository root:

PYTHONPATH=src python -m unittest discover -s tests -v
python -m compileall -q src tests

npm --prefix node ci
npm --prefix node test
npm --prefix node run test:package

node scripts/check-versions.mjs

See CONTRIBUTING.md for contributor guidance and node/README.md for Node.js-specific implementation and packaging details and npm CLI usage.

Metadata

Release files for align-dotenv 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for align-dotenv 0.3.1
File Size Uploaded
align_dotenv-0.3.1.tar.gz 11.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for align-dotenv 0.3.1
File Interpreter ABI Platform
align_dotenv-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 23.4 kB

Release files / align_dotenv-0.3.1.tar.gz

Download URL align_dotenv-0.3.1.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
16e46ab5e378e768d7f55b13b7ddeb853522e54f6822408c1dcf7b9fe6be4dd7
BLAKE2b-256 checksum
How to use checksums
c32a10698af4c9005137ecc1dcf906d958d54a621d002a9d5c14d1074585bdfe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / align_dotenv-0.3.1-py3-none-any.whl

Download URL align_dotenv-0.3.1-py3-none-any.whl
Size 11.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60db20c8a348a451dfef1f9101ff1de5dabc9912e4a9cb5b9ded3cde26d5c2ba
BLAKE2b-256 checksum
How to use checksums
f52c9da9b28c23ccf314e9f2a85f9024b6ac36e1941fb35d1d10ad1dcdb27c26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page