Skip to main content

npm

Source

Description

Functional utilities for reading and parsing environmental variables, based on Wolfstar’s internal tools.

Loaders

setup() needs no other package. By default, it parses .env* files with Node.js’ own util.parseEnv, the node loader, which requires Node.js 20.12 or newer. dotenv and dotenv-expand are optional peer dependencies. Install both if you want the dotenv loader:
setup() picks a loader in this order when you do not choose one:
  1. varlock: when the project has a varlock schema. See Experimental: varlock support.
  2. dotenv: when both dotenv and dotenv-expand are installed.
  3. node: otherwise. It expands $VAR, ${VAR}, ${VAR:-default}, ${VAR:+alternate}, and \$ the same way dotenv-expand does.
Set the loader option or the DOTENV_LOADER environment variable to 'node', 'dotenv', or 'varlock' to choose one yourself. If you ask for dotenv without the packages installed, setup() throws an Error that names the missing package.

Usage

Setup

To setup @wolfstar/env-utilities, you use the setup function exported by the package:
Alternatively, if you do not need to provide any custom options you can import it as a side effect:
You can also pass a string or if you want to define other options, you may use EnvSetupOptions. Optionally, you may configure dotenv via environment variables:
  • DOTENV_DEBUG: configures EnvSetupOptions.debug. If enabled, the library will log to help debug why certain keys or values are not being set as expected.
  • DOTENV_ENCODING: configures EnvSetupOptions.encoding. If set, it will specify the encoding of the files containing the environment variables
  • DOTENV_ENV: configures EnvSetupOptions.env. If set, it will specify a custom environment if NODE_ENV is not sufficient.
  • DOTENV_PATH: configures EnvSetupOptions.path. If set, it will specify a custom path to the file containing environment variables, useful for when they are located elsewhere.
  • DOTENV_PREFIX: configures EnvSetupOptions.prefix. If set, it will specify a required prefix for dotenv variables (e.g. APP_).
  • DOTENV_LOADER: configures EnvSetupOptions.loader. If set, it selects the node, dotenv, or varlock loader instead of detecting one.

With the stars CLI

A bot built with the stars CLI (@wolfstar/cli) on compatibility version 5 does not call setup() itself. The env option of stars.config mirrors EnvSetupOptions, and stars calls setup() with it before any module of the bot runs. Do not call setup() by hand as well. Options set in stars.config take precedence over the DOTENV_* variables above, the same way options passed to setup() do.
stars.config.ts
See Environment variables for when this registration turns on.

What .env files can be used?

Every file below is searched first under src/, then at the project root. An explicit path or DOTENV_PATH disables this discovery and uses that base path only.
  • .env: Default.
  • .env.local: Local overrides. This file is loaded for all environments except test.
  • .env.development, .env.test, .env.production: Environment-specific settings.
  • .env.development.local, .env.test.local, .env.production.local: Local overrides of environment-specific settings.
Files on the left have more priority than files on the right:
  • npm start: .env.development.local, .env.local, .env.development, .env
  • npm test: .env.test.local, .env.test, .env (note .env.local is missing)
CRA Reference

Experimental: varlock support

@wolfstar/env-utilities can optionally delegate environment variable resolution to varlock, a schema-based alternative to dotenv with built-in validation, type-safety, and secret protection. Support for varlock is experimental. Use it when you want varlock’s .env.schema validation instead of the built-in .env* discovery. First, set up varlock in your project and install the optional varlock peer dependency:
setup() then picks varlock by itself when the project has a schema. It looks for, in order:
  • src/.env.schema, looked up first like src/.env*.
  • .env.schema at the project root.
  • A varlock.loadPath in package.json.
An explicit path or DOTENV_PATH disables this detection. The loader option and the DOTENV_LOADER environment variable always take precedence:
If your project already has a .env.schema and varlock installed but loaded its .env* files through dotenv, detection now switches it to varlock. Varlock does its own .env* discovery, so the values can differ. Set loader: 'dotenv' to opt out.
With the varlock loader, setup() runs varlock load --format json-full to resolve your checked-in .env.schema, then injects the result into process.env:
  • path and env are passed to varlock as --path and --env. encoding is ignored in favour of the schema.
  • prefix still applies to the returned parsed map. That map holds exactly the variables the schema resolved, as strings, with @internal items left out.
  • An invalid schema makes setup() throw an Error carrying varlock’s summary, instead of exiting the process.
  • Varlock’s runtime redaction and leak detection are not part of the CLI. Add import 'varlock/auto-load' to opt into them.
  • path and env cannot contain whitespace. The one exception is a path that points to a directory with whitespace in its name.
If you select the varlock loader without installing the varlock package, setup() throws an error asking you to install it (for example, pnpm add varlock).

Typing Environment Variables

To add new entries, you augment Env from @wolfstar/env-utilities/dist/lib/types using any of the following types:
  • BooleanString: can be parsed with envParseBoolean.
  • IntegerString: can be parsed with envParseInteger.
  • NumberString: can be parsed with envParseNumber.
  • string: can be parsed with envParseString and envParseArray.
The above 5 functions throw a ReferenceError instance if a key is missing, unless you pass a default in the second parameter. They throw a TypeError instance if a key cannot be parsed. The functions return the default value as-is without validating it. An example of adding more keys is as it follows:

With a varlock schema

With varlock, the .env.schema is the source of truth, and its @generateTsTypes decorator writes the typings (CoercedEnvSchema, EnvSchemaAsStrings, and others). Instead of declaring every variable a second time in Env, derive it from the generated CoercedEnvSchema with EnvFromVarlock:
EnvFromVarlock is also exported from the package root. It maps:
  • boolean to BooleanString, so envParseBoolean accepts the key.
  • number to a string that is both an IntegerString and a NumberString, so both envParseInteger and envParseNumber accept the key. The coerced type cannot tell an integer from a float, so envParseInteger throws at runtime when the key holds a value like 1.5. Use envParseNumber for decimal values.
  • string and enum to their string form, so envParseString accepts the key. An enum whose values look like numbers or booleans ('1' | '2') is widened with string, so it stays a string key.
  • Optional keys to optional keys.
  • Anything else, like an array, to a plain string.
EnvFromVarlock leaves out NODE_ENV. Env keeps declaring it as 'test' | 'development' | 'production', so a schema with a narrower NODE_ENV still compiles. Varlock serializes an array with its own separator (, by default), while envParseArray splits on spaces. Read such a variable through env instead (see below).

Read coerced values with env

@wolfstar/env-utilities/varlock also exports env, the ENV object of varlock/env. When setup() loads a schema with the varlock loader, env holds values that varlock already validated and coerced, typed by the file varlock generates:
Use env in new code of a varlock project. Keep envParse* for code that has not moved yet, for projects without varlock, and for values read straight from process.env. Both work side by side, so you can migrate one call at a time. Importing @wolfstar/env-utilities/varlock requires the varlock package.