New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

env-interpolation

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

env-interpolation

A lightweight, zero-dependency utility for recursively interpolating ${VAR:default} placeholders in strings, objects, and arrays.

latest
Source
npmnpm
Version
1.1.1
Version published
Maintainers
1
Created
Source

env-interpolation

NPM Version CI codecov License: MIT

Recursively resolve ${VAR} style placeholders in strings, objects, or arrays using environment variables or custom maps.

Features

  • Works with strings, plain objects, and arrays without mutating the original input.
  • Falls back to process.env automatically; pass your own variable map for custom contexts.
  • Supports defaults (${NAME:Guest}) including quoted values and nested placeholders.
  • Handles nested interpolation across multiple passes while preventing infinite loops.
  • Escape placeholders with backslashes (\\${VAR}) or disable escaping entirely when needed.
  • Ships with full TypeScript definitions and preserves the structural type of the input.

Installation

npm install env-interpolation
# or
yarn add env-interpolation
# or
pnpm add env-interpolation

Requirements:

  • Node.js 18 or higher
  • Supports both ESM (import) and CommonJS (require)

Quick Start

ESM (import)

import { interpolate } from "env-interpolation";

const greeting = interpolate("Hello ${NAME:Guest}!", { NAME: "Ada" });
// "Hello Ada!"

const config = interpolate({
  url: "${API_URL:https://api.example.com}",
  timeout: "${TIMEOUT:5000}",
  features: ["${FEATURE_PRIMARY:alpha}", "${FEATURE_SECONDARY:beta}"],
});
// All placeholders resolved using process.env by default

CommonJS (require)

const { interpolate } = require("env-interpolation");

const greeting = interpolate("Hello ${NAME:Guest}!", { NAME: "Ada" });
// "Hello Ada!"

const config = interpolate({
  url: "${API_URL:https://api.example.com}",
  timeout: "${TIMEOUT:5000}",
  features: ["${FEATURE_PRIMARY:alpha}", "${FEATURE_SECONDARY:beta}"],
});
// All placeholders resolved using process.env by default

Placeholder syntax

  • ${VAR} — looks up VAR in the variable map or process.env.
  • ${VAR:Default} — uses Default when VAR is missing or undefined.
  • ${VAR:'Quoted value'} or ${VAR:"Quoted value"} — quotes let you keep colons or other placeholders in defaults. Both single and double quotes are stripped.
  • Invalid variable names (anything beyond letters, numbers, and _) are left untouched.
  • Defaults can contain nested placeholders; they are resolved in subsequent passes.

API

interpolate<T>(content, variables?, options?)

  • content (T extends string | Record<string, unknown> | unknown[]): value (or structure) to process.
  • variables (Record<string, string | undefined>): optional override map. Defaults to process.env when available.
  • options:
    • escape (boolean, default true): when enabled, a single preceding backslash escapes a placeholder (\\${VAR}${VAR}). Disable to treat backslashes as literal characters.
    • maxPasses (number, default 10): maximum interpolation passes. Lower to cap work on pathological nesting; raise to resolve deeper chains.

Returns the interpolated value while preserving the original shape and TypeScript type.

Behavior notes

  • Resolution runs up to 10 passes to support nesting while protecting against infinite substitution loops.
  • Empty defaults (${VAR:}) leave the placeholder intact so you can detect missing configuration.
  • Arrays and objects are traversed deeply; non-string primitives are returned untouched.

Escaping examples

import { interpolate } from "env-interpolation";

interpolate("Literal \\${PASSWORD}");
// "Literal ${PASSWORD}" (escape enabled, the placeholder is left as-is)

interpolate("Literal \\${PASSWORD}", { PASSWORD: "secret" }, { escape: false });
// "Literal \\secret" (escape disabled, placeholder still resolves)

TypeScript aware

The exported function is fully typed. The returned value retains the structural type of the input, so narrowed types stay intact:

import { interpolate } from "env-interpolation";

const settings = {
  port: "${PORT:3000}",
  flags: ["${PRIMARY_FLAG:enabled}", "${SECONDARY_FLAG:disabled}"],
} as const;

const result = interpolate(settings);
// result has the same readonly structure as `settings`

Security Considerations

⚠️ Warning: Interpolating secrets into logs or HTML can leak sensitive information. Prefer resolving variables at the application edge and redacting secrets in logs.

Browser Usage

Since process.env isn't available in browsers, pass variables explicitly:

import { interpolate } from "env-interpolation";

const config = {
  apiUrl: "${API_URL:https://api.example.com}",
  timeout: "${TIMEOUT:5000}",
};

const result = interpolate(config, {
  API_URL: "https://prod-api.example.com",
  TIMEOUT: "10000",
});

Testing & development

  • npm run test – run the Vitest suite (covers string, object, and array interpolation).
  • npm run lint – lint sources with ESLint.
  • npm run build – produce the bundled output via tsup.

Contributing

Contributions and bug reports are welcome! Read the CONTRIBUTING.md guide and adhere to the CODE_OF_CONDUCT.md when participating. Issues and pull requests live at the GitHub repository.

License

Released under the MIT License.

Keywords

environment

FAQs

Package last updated on 07 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts