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:
varlock: when the project has a varlock schema. See Experimental: varlock support.dotenv: when bothdotenvanddotenv-expandare installed.node: otherwise. It expands$VAR,${VAR},${VAR:-default},${VAR:+alternate}, and\$the same waydotenv-expanddoes.
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:
string or if you want to define other options, you may use EnvSetupOptions. Optionally, you may configure dotenv via environment variables:
DOTENV_DEBUG: configuresEnvSetupOptions.debug. If enabled, the library will log to help debug why certain keys or values are not being set as expected.DOTENV_ENCODING: configuresEnvSetupOptions.encoding. If set, it will specify the encoding of the files containing the environment variablesDOTENV_ENV: configuresEnvSetupOptions.env. If set, it will specify a custom environment ifNODE_ENVis not sufficient.DOTENV_PATH: configuresEnvSetupOptions.path. If set, it will specify a custom path to the file containing environment variables, useful for when they are located elsewhere.DOTENV_PREFIX: configuresEnvSetupOptions.prefix. If set, it will specify a required prefix for dotenv variables (e.g.APP_).DOTENV_LOADER: configuresEnvSetupOptions.loader. If set, it selects thenode,dotenv, orvarlockloader 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
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.
npm start:.env.development.local,.env.local,.env.development,.envnpm test:.env.test.local,.env.test,.env(note.env.localis missing)
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 likesrc/.env*..env.schemaat the project root.- A
varlock.loadPathinpackage.json.
path or DOTENV_PATH disables this detection. The loader option and the DOTENV_LOADER environment variable always take precedence:
setup() runs varlock load --format json-full to resolve your checked-in .env.schema, then injects the result into process.env:
pathandenvare passed to varlock as--pathand--env.encodingis ignored in favour of the schema.prefixstill applies to the returnedparsedmap. That map holds exactly the variables the schema resolved, as strings, with@internalitems left out.- An invalid schema makes
setup()throw anErrorcarrying 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. pathandenvcannot contain whitespace. The one exception is apaththat points to a directory with whitespace in its name.
varlock package, setup() throws an error asking you to install it (for example, pnpm add varlock).
Typing Environment Variables
To add new entries, you augmentEnv from @wolfstar/env-utilities/dist/lib/types using any of the following types:
BooleanString: can be parsed withenvParseBoolean.IntegerString: can be parsed withenvParseInteger.NumberString: can be parsed withenvParseNumber.string: can be parsed withenvParseStringandenvParseArray.
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:
booleantoBooleanString, soenvParseBooleanaccepts the key.numberto a string that is both anIntegerStringand aNumberString, so bothenvParseIntegerandenvParseNumberaccept the key. The coerced type cannot tell an integer from a float, soenvParseIntegerthrows at runtime when the key holds a value like1.5. UseenvParseNumberfor decimal values.stringandenumto their string form, soenvParseStringaccepts the key. An enum whose values look like numbers or booleans ('1' | '2') is widened withstring, so it stays a string key.- Optional keys to optional keys.
- Anything else, like an
array, to a plainstring.
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:
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.