# Environment variables Import `env` from `avril:std`: ```ts import { env, pledge } from "avril:std"; const token = env.get("API_TOKEN"); env.delete("API_TOKEN"); pledge({ env: false }); // Pass the captured token explicitly to code that needs it. ``` `env` starts with a snapshot of the inherited process environment. Its mutations are local to avril: they do not change the host process environment or native libraries' configuration. - `env.get(name)` returns a string, or `undefined` if the variable is absent. - `env.has(name)` tests presence; an empty string is still a present value. - `env.set(name, value)` creates or replaces a variable. - `env.delete(name)` removes a variable; removing an absent variable is a no-op. - `env.toObject()` returns an independent, mutable, null-prototype object containing only permitted variables. Changing it does not change the environment store. All four named operations require permission for that name, even when the variable is absent. Permission failures use `errors.PermissionDenied` from `avril:std`. Names must be nonempty and contain neither `=` nor NUL. Values may be empty but cannot contain NUL. Invalid names and values use `errors.InvalidInput`. Names and values are converted to well-formed strings; symbols are rejected. Host variables with non-UTF-8 names or values are omitted rather than lossily decoded. Names are case-sensitive on Unix and ASCII case-insensitive on Windows. ## Permissions Environment access is allowed by default. `-0` disables it along with the other ambient capabilities. Grant individual names with repeatable flags: ```sh avril run -0 --allow-env=API_TOKEN --allow-env=MODE main.ts avril run --deny-env=API_TOKEN main.ts ``` Names are exact, not patterns or comma-separated lists. Explicit denials win over grants, regardless of flag order. Granting environment access does not grant filesystem, network, or module execution access. `pledge` narrows environment authority just like other capabilities: ```ts pledge({ env: { allow: ["MODE"], deny: ["API_TOKEN"] } }); pledge({ env: false }); ``` Omitted categories are unchanged. Successive pledges intersect allowed names and accumulate denials; they cannot restore authority. An invalid pledge does not partially change permissions. Retained methods recheck current permissions, but previously captured strings and snapshots remain usable. Static imports execute before the importing module's body. Use startup permissions if dependencies must never see a secret, or capture and delete secrets before loading dependencies with dynamic imports. ## Environment files `avril run` accepts repeatable `--env-file=PATH` or `--env-file PATH` flags. Paths are relative to the current working directory, not the entry module's directory. Use the equals form (or a `./` prefix) for filenames beginning with `-`. ```sh avril run -0 --allow-env=API_TOKEN --env-file=.env --env-file=.development.env main.ts ``` Inherited environment values take precedence, including empty strings. Later files override earlier files, and the last assignment to a name within a file wins. There is no implicit `.env` discovery. Missing, unreadable, non-UTF-8, or NUL-containing files stop startup before JavaScript runs; diagnostics do not echo file contents. Naming an env file authorizes the CLI to load it, even with `-0` or read denials, but grants **no environment or filesystem authority** to JavaScript. Under `-0`, each variable still requires `--allow-env=NAME`, whether its value comes from a file or the inherited environment. Explicit `--deny-env` rules still win, and `pledge` can subsequently remove authority. Loading values and granting access are separate operations. The dotenv syntax follows Node 24's conventions, with more predictable handling of indented comments, empty names, and whitespace-only empty values: - Assignments use `NAME=value`; surrounding spaces and tabs are trimmed. - Blank lines, indented comments, lines without an assignment, and assignments with empty names are ignored. - `#` begins a comment outside a quoted value. - Values enclosed in single quotes, double quotes, or backticks retain their interior whitespace and may span multiple lines. - Double-quoted values expand literal `\n` sequences into newlines. Other escapes and variable references such as `$NAME` or `${NAME}` remain literal. - An `export ` prefix is ignored. Empty values are empty strings, including exported assignments and values followed only by whitespace. - CRLF is supported, and an initial UTF-8 BOM is ignored. - Text after a closing quote on the same line is ignored. If no matching closing quote exists anywhere later in the file, the value is kept literally through the end of its first line. File values enter only the runtime-local env store. Unlike Node's flag, they do not configure native libraries or CLI settings such as `AVRIL_CACHE_DIR`, and `NODE_OPTIONS` has no special meaning.