Environment
The environment a script sees is built in four layers. Later layers win.
PATH is rebuilt between layers 1 and 2, described below.
env
A map of literal values, applied last.
An env entry wins over the machine's value for the same variable. That is the difference between
env and envFile: env is a decision made in the config, so it takes effect.
envFile
A dotenv file, read relative to the config that declared it.
A file never overrides a variable that is already set. An assignment whose variable exists in the environment is skipped, and the skip is reported on stderr with the variable, the file and the reason:
This makes a one-off override work the way it looks like it should:
Without the rule, the file would silently win and the command above would do nothing.
A missing envFile is an error, not a warning. A test suite that runs against the wrong database
because a file was renamed is worse than a failed run. The message names the script, the path the
file resolved to, and the config that declared it. A line that cannot be parsed as an assignment is
an error too, naming the file and the line number.
Across an extends chain
Every level of an extends chain contributes its own envFile, and each one fills gaps only. The
files are consulted from the level nearest the script outward, so the nearer config wins a variable
both of them set, and the outer file's assignment is reported as ignored — the same way a config
narrowing what it inherits narrows its env map.
The RUNE_ prefix
Names beginning with RUNE_ are reserved. An attempt to set one from a file or from an env map is
ignored and reported:
Rune sets three of them for every script:
PATH
Rune prepends every node_modules/.bin directory from the package directory up to the config root,
most specific first, using the platform separator.
Every level in between is included, not just the two ends. For a run in packages/api of a
repository rooted at /repo:
Order decides which copy of a tool wins. A package that pinned an older version of a tool gets its own copy, not the root's. Directories that do not exist are still added, matching npm, so a directory created later lands in the right position without a re-run.
This is what makes "command": "vitest run" work with no path and no npx.
Windows
Environment variable names are case-insensitive on Windows and the operating system enforces that,
not the caller. Rune merges case-insensitively there, so a child never receives both PATH and
Path. The name is preserved as the parent wrote it, so a machine that says Path hands the child
Path.
Seeing the result
rune inspect prints what the config contributes, including the assignments that were ignored.
PATH and the three RUNE_ variables are not in the delta. Rune sets them for every script, so
listing them would say nothing about this one.