Maintainers of Node and Vite/React apps who keep a .env.example as the contract for required configuration: this tool scans process.env and import.meta.env usages in source and fails when keys are missing from .env.example (warnings for unused example keys). Unlike dotenv-linter or eslint-plugin-n (which focus on dotenv syntax or Node globals), env-example-sync is a focused source↔example sync check for CI.
# from the repository root
npm install
npm test
node bin/env-example-sync.js --help
node bin/env-example-sync.js fixtures/synced
# expect exit 1 (missing keys):
node bin/env-example-sync.js fixtures/missing-key || true
# expect exit 0 with WARN unused:
node bin/env-example-sync.js fixtures/unused-key# from the repository root
npm install
npm test
node bin/env-example-sync.js --help
node bin/env-example-sync.js fixtures/synced
# expect exit 1 (missing keys):
node bin/env-example-sync.js fixtures/missing-key; if ($LASTEXITCODE -eq 0) { throw "expected failure" }
# expect exit 0 with WARN unused:
node bin/env-example-sync.js fixtures/unused-keynpm install --save-dev env-example-syncOr run from this package directory after npm install && npm run build.
env-example-sync [options] [rootDir]
Options:
-h, --help Show help
-v, --version Show version
-e, --example <path> Env example file (default: <root>/.env.example)
-j, --json JSON report
--root <dir> Project root (default: cwd)
Exit codes: 0 = no missing keys (unused keys only warn). 1 = one or more keys used in source but absent from .env.example. 2 = usage/IO error.
- uses: ./ # or owner/env-example-sync@v0.1.0 when published
with:
root: "."
example: ".env.example"
fail-on-unused: "false"| Input | Default | Description |
|---|---|---|
root |
. |
Project root to scan |
example |
.env.example |
Path to env example file |
fail-on-unused |
false |
If true, unused example keys also fail the job |
process.env.KEY,process.env["KEY"],process.env['KEY'], optional chainingprocess.env?.KEYimport.meta.env.KEYand bracket forms (Vite-style)
Scans .js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts, .vue, .svelte. Skips node_modules, dist, build, .git, and similar.
| Fixture | Behavior |
|---|---|
fixtures/synced |
Source and .env.example match → exit 0 |
fixtures/missing-key |
Source uses keys absent from example → exit 1 |
fixtures/unused-key |
Example has unused LEGACY_TOKEN → warn, exit 0 |
import { syncEnvExample, exitCodeForResult } from "env-example-sync";
const result = syncEnvExample({ rootDir: "." });
process.exit(exitCodeForResult(result));- Does not resolve dynamic keys (
process.env[name], template keys). - Does not parse
Deno.env.get/Bun.env/os.environ. - Does not merge multiple example files or
.env*.localvariants beyond--example. - Regex-based scan (not a full TS AST); unusual formatting may be missed.
- Does not suggest auto-fix of
.env.example(check-only in v0.1).
MIT