bun/no-env-at-module-scope
Disallow reading environment variables as soon as the module is loaded
A variable that's read at the top level of a file is read once, when the file is first imported. A test that sets process.env.API_URL after the import has no effect, and neither does code that loads the environment later. The module's behavior then depends on import order. Read the variable in the function that needs it.
The rule knows process.env, Bun.env, import.meta.env, and env imported from node:process. Assigning to a variable or deleting one isn't reported.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"bun/no-env-at-module-scope" = "error" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"bun/no-env-at-module-scope" = ["error", {
allow = ["NODE_ENV"],
}]Examples#
example.js1 problem
const apiUrl = process.env.API_URLprocess.env.API_URL is read as soon as the module is imported. Read it inside the function that needs it.;
export function fetchUser(id) {
return fetch(`${apiUrl}/users/${id}`);
}example.js3 problems
import { env } from "node:process";
const { API_URL, API_KEY } = Bun.envThe environment is read as soon as the module is imported. Read it inside the function that needs it.;
const settings = { ...import.meta.envThe environment is read as soon as the module is imported. Read it inside the function that needs it. };
const port = Number(env.PORTenv.PORT is read as soon as the module is imported. Read it inside the function that needs it.);example.jsNo problems
export function fetchUser(id) {
return fetch(`${process.env.API_URL}/users/${id}`);
}example.jsNo problems
process.env.TZ = "UTC";
const isProduction = process.env.NODE_ENV === "production";Options#
| Option | Default | What it does |
|---|---|---|
allow | ["NODE_ENV"] | Names of variables that can be read at the top level. It replaces the default list. |
example.jswith
{ "allow": ["NODE_ENV", "CI"] }No problemsconst isCI = process.env.CI === "true";
const { NODE_ENV, CI } = process.env;example.jswith
{ "allow": ["CI"] }1 problemconst isProduction = process.env.NODE_ENVprocess.env.NODE_ENV is read as soon as the module is imported. Read it inside the function that needs it. === "production";When not to use it#
A file like env.ts or config.ts that reads and checks the environment once at startup is doing this on purpose. Turn the rule off for that file.