Nub has first-party support for Varlock, a tool that loads and validates the environment against a declarative schema file, .env.schema.

.env.schema
# @defaultSensitive=false
# @generateTypes(lang="ts", path="env.d.ts")
# ---

# @required @type=port
PORT=3000

# @required @type=enum(development, staging, production)
APP_ENV=development

# @required @sensitive @type=url
DATABASE_URL=

When Nub finds a .env.schema, it turns off its own environment loading and hands the environment to Varlock for every file and script it runs.

nub index.ts
nub run dev

Varlock invocations you write yourself run exactly as written. A script that calls Varlock directly keeps its own flags, and Nub does not add a second Varlock run in front of it.

package.json
{
  "scripts": {
    "build": "varlock run --path ./config -- node build.js"
  }
}

Nub looks for the schema in the package you are running, then walks up to the workspace root. The nearest one wins, so a package with its own schema keeps it.

A project that depends on dotenv-extended, which uses the .env.schema name for its own format, keeps Nub's own environment loading.

Installing Varlock

Nub uses the Varlock already on your machine, checking the project first and then PATH. A command that launches your code fails when it finds neither:

$ nub index.ts
Error: .env.schema needs varlock, which isn't installed.
Run `nub add -D varlock`.

Overriding the hand-over

An explicit envFile setting wins over the schema, and Varlock stays out of the chain.

nub.jsonc
{
  "envFile": [".env"]  // load this, not the schema; false loads nothing
}

The --env-file and --no-env-file flags do the same for a single run, and also clear the missing-Varlock error. Use them to run a schema project on a machine where Varlock will not install.

The setting works at every scope, so nub config set --global envFile false reaches schema projects too. To keep Varlock in one project regardless, select it explicitly.

nub.jsonc
{
  "envFile": "varlock"  // keep Varlock, whatever the global config says
}

Read the full docs for Varlock on varlock.dev.