dotenv-expand

Expands variable references, command substitution, and encrypted values in dotenv-parsed .env files.

Library
npm
v1000.0.0
1,057stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
63/100Good
Development Activity68
Maintenance40
Community56
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture78
Code Quality75
Innovation65
Learning Curve60

dotenv-expand extends dotenv with variable interpolation, letting one .env value reference another via ${VAR} or $VAR syntax, along with default and alternate value fallbacks. It also supports command substitution via $(command) and can decrypt dotenvx-encrypted values when a private key is present in the environment.

Built as a thin orchestration layer over the @dotenvx/primitives package, it’s typically chained directly after dotenv.config() to expand the parsed result before it’s written into process.env, making layered and cross-referencing .env configuration possible without introducing a full templating engine.

What You Get

  • Variable expansion that resolves ${VAR} and unbraced $VAR references against process.env and already-expanded keys
  • Default and alternate value syntax — ${MISSING:-default} and ${BASIC:+alternate} — for conditional fallbacks
  • Command substitution — $(command) executes and inlines shell output into a value
  • Encrypted value decryption — automatically decrypts dotenvx encrypted: values when DOTENV_PRIVATE_KEY is set
  • Preload support via node -r dotenv-expand/config, expanding .env before your app starts with no separate dotenv install required

Common Use Cases

  • Composing DATABASE_URL from separately defined HOST/PORT/USER variables
  • Preloading expanded env vars into a script via -r dotenv-expand/config in CI or npm scripts
  • Deriving a value at load time with command substitution, e.g. capturing node --version into an env var
  • Shipping dotenvx-encrypted .env files that only decrypt into expanded values when a DOTENV_PRIVATE_KEY is supplied at runtime

Under The Hood

Architecture lib/main.js exports a single expand(options) function that takes options.parsed (the key-value map from dotenv.config()) and iterates each key while building up a runningParsed object for progressive expansion, so later variables can reference earlier ones already resolved within the same call. For each value it first checks a short-circuit case: if the target processEnv already holds a different value for that key, the pre-existing value wins untouched. Otherwise it builds a shadow copy of processEnv, strips entries that just mirror unexpanded literals (so already-expanded values from the running pass are preferred over raw pass-through data dotenv may have set), checks for a DOTENV_PRIVATE_KEY against dotenvx’s encrypted: convention and decrypts via @dotenvx/primitives, then calls that package’s expand and evaluate helpers for substitution and command evaluation. A thin config.js wrapper combines dotenv’s own CLI-arg/env-var option parsing with this expand() to power the -r dotenv-expand/config preload entrypoint. All substitution/decryption logic lives in the separate @dotenvx/primitives package; this repo is the orchestration layer over dotenv’s parsed output rather than a self-contained implementation.

Tech Stack Plain CommonJS JavaScript with no framework — 'use strict', require/module.exports throughout. The only runtime dependency is the first-party @dotenvx/primitives package (pinned to 2.1.1 in devDependencies alongside dotenv ^17.4.2 for testing), which supplies decrypt, encrypted, evaluate, and expand. The build uses esbuild to bundle lib/main.js and config.js into dist/ as CJS targeting Node 16, with hand-written type declarations in lib/main.d.ts validated separately against tests/types via tsc. Linting is done with Biome rather than ESLint/Prettier. Deployment target is npm registry publish, with prepack running the esbuild build and prepublishOnly doing a dry-run pack check.

Code Quality Tests live in tests/main.js using a small custom tap-style harness (tests/test.js), covering expansion, self-referential expansion (guarding against infinite recursion), default/alternate value syntax, encrypted-value decryption using @dotenvx/primitives’ encrypt/keypair helpers directly in the test file, and pre-existing process.env short-circuiting, with deliberate process.env = {} reset in beforeEach for isolation. npm test runs the harness directly with node, no external test-runner dependency. The pretest script chains Biome lint and a dts-check (tsc against tests/types/tsconfig.json), so type declarations are validated even though the library itself isn’t authored in TypeScript. Error handling is intentionally non-throwing — unexpandable or self-referential values resolve to an empty string rather than raising, a reasonable choice for a startup-time env loader that shouldn’t crash a caller’s boot sequence. Naming is short and consistent (_resolveEscapeSequences, runningParsed, literals).

API Design The public surface is a single expand(options) function accepting { parsed, processEnv? }, mirroring dotenv’s own config() return shape so the two chain naturally: dotenvExpand.expand(dotenv.config()). This keeps boilerplate minimal — one extra line after the existing dotenv call — and the optional processEnv override lets callers redirect expansion into an object other than process.env without any additional API surface. Naming and option shapes deliberately parallel dotenv’s own conventions, reducing the learning curve for anyone already using dotenv. Documentation in the README is thorough, with worked examples for every feature (preload, command substitution, encrypted values, custom processEnv, interpolation syntax) presented as collapsible detail blocks.

Used by 13 apps in this directory

TypeScript
72%
AGPL 3.0

APITable

Low Code Platforms · Databases

15,588

API-first collaborative spreadsheet-database platform that auto-generates REST APIs and lets teams build internal tools, CRMs, and dashboards without code.

View details
74
Repo Health
77
Technical
60
Dependency
Built with
TypeScript72%
Java22%
Updated yesterday
TypeScript
68%
Apache 2.0

Appsmith

Developer Tools · Automation · No Code Platforms

40,825

Open-source low-code platform to build admin panels, dashboards, and internal tools connected to any database or API.

View details
93
Repo Health
79
Technical
66
Dependency
Built with
TypeScript68%
Java21%
Updated 3 days ago
JavaScript
99%
Other

ChartBrew

Analytics · Databases

4,054

Open-source reporting platform to build live dashboards from SQL, NoSQL, APIs, and SaaS tools with an AI assistant that creates charts from natural language.

View details
90
Repo Health
83
Technical
64
Dependency
Built with
JavaScript99%
Updated 4 days ago
TypeScript
76%
AGPL 3.0

Ghostfolio

Invoicing Finance

9,252

Track your stocks, ETFs, and crypto with a privacy-first, self-hostable wealth management platform built for data-driven investors.

View details
93
Repo Health
79
Technical
67
Dependency
Built with
TypeScript76%
HTML21%
Updated yesterday
TypeScript
96%
MIT

HyperDX

Developer Tools · Analytics · Monitoring

9,873

Open source observability platform that unifies logs, traces, metrics, and session replays on ClickHouse — now the core of ClickStack.

View details
88
Repo Health
83
Technical
68
Dependency
Built with
TypeScript96%
Updated yesterday
TypeScript
98%
Other

Langfuse

AI Development · Monitoring

34,264

Open source AI engineering platform for LLM observability, prompt management, evaluation, and debugging — self-host in minutes or use Langfuse Cloud.

View details
92
Repo Health
81
Technical
66
Dependency
Built with
TypeScript98%
Updated yesterday
TypeScript
94%
AGPL 3.0

Laudspeaker

Marketing · Automation

2,620

Open-source customer engagement platform for building visual, event-triggered messaging journeys across email, SMS, push, in-app, and webhooks.

View details
51
Repo Health
66
Technical
62
Dependency
Built with
TypeScript94%
Updated 1 months ago
TypeScript
99%
Other

LobeHub

AI Assistants · Productivity · Automation

82,273

Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.

View details
92
Repo Health
81
Technical
69
Dependency
Built with
TypeScript99%
Updated today
TypeScript
86%
MIT

medusa

Ecommerce

36,163

The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.

View details
93
Repo Health
87
Technical
63
Dependency
Built with
TypeScript86%
JavaScript14%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search