{"record":{"id":"2cdc4c231f7e18d7","repo":"oxc-project/oxc","slug":"disallowed-usage-of-process-env","errorCode":null,"errorMessage":"Disallowed usage of `process.env`.","messagePattern":"Disallowed usage of `process\\.env`\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/node/no_process_env.rs","lineNumber":19,"sourceCode":"use oxc_ast::AstKind;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::IsGlobalReference;\nuse oxc_span::{GetSpan, Span};\nuse oxc_str::CompactStr;\nuse oxc_str::static_ident;\nuse rustc_hash::FxHashSet;\nuse schemars::JsonSchema;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_process_env_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Disallowed usage of `process.env`.\")\n        .with_help(\"Remove usage of `process.env`.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\nstruct NoProcessEnvConfig {\n    /// Variable names which are allowed to be accessed on `process.env`.\n    allowed_variables: FxHashSet<CompactStr>,\n}\n\n#[derive(Debug, Default, Clone, Deserialize, Serialize)]\npub struct NoProcessEnv(Box<NoProcessEnvConfig>);\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallows use of `process.env`.","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/node/no_process_env.rs#L1-L37","documentation":"Diagnostic from oxlint rule node/no-process-env (restriction). It disallows direct reads of process.env so that environment configuration flows through one audited module instead of being scattered across the codebase — scattered reads are hard to inventory, easy to get wrong (undefined vs empty string), and impossible to type. The allowedVariables option allowlists specific variable names; the default configuration allows none.","triggerScenarios":"Any member access on process.env — process.env.NODE_ENV, process.env['API_KEY'] — where the accessed variable name is not in the configured allowedVariables FxHashSet (camelCase JSON key). With default options the set is empty, so every process.env access in the file reports with the property's span labeled.","commonSituations":"12-factor apps expected to read config in a single config.js; monorepos with shared oxlint configs banning scattered env reads; migrations from eslint-plugin-n where the allowedVariables lists must be re-entered; teams wanting typed config via zod/envalid at one boundary.","solutions":["Centralize: read process.env once in a config module (ideally validated with envalid/zod) and import typed values everywhere else","Allowlist vetted names: \"node/no-process-env\": [\"error\", { \"allowedVariables\": [\"NODE_ENV\"] }]","Pass configuration explicitly as function/constructor parameters so modules stay env-agnostic","In Next.js client code, prefer NEXT_PUBLIC_* build-time inlining instead of runtime process.env reads"],"exampleFix":"// before (scattered)\nconst port = process.env.PORT;\nconst key = process.env.API_KEY;\n\n// after: single audited reader, e.g. config.js\n// config.js\nconst env = (name) => {\n  const v = process.env[name]; // the one allowed place\n  if (!v) throw new Error(`Missing env var: ${name}`);\n  return v;\n};\nmodule.exports = { port: Number(env('PORT')), apiKey: env('API_KEY') };","handlingStrategy":"validation","validationCode":"// .oxlintrc.json\n\"rules\": {\n  \"node/no-process-env\": [\"error\", { \"allowedVariables\": [\"NODE_ENV\"] }]\n}\n\nnpx oxlint -c .oxlintrc.json --deny-warning .","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Route every env read through one validated config module (envalid/zod) so this rule has exactly one sanctioned file","Fail fast on missing variables at startup with clear messages instead of scattering process.env across modules","Prefer explicit dependency injection into modules so business logic is testable without env trickery"],"tags":["node","configuration","environment-variables","restriction","oxlint"],"backgroundTag":"process-env-access","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}