oxc-project/oxc · warning · OxcDiagnostic
Unexpected require().
Error message
Unexpected require().
What it means
Diagnostic from oxlint rule node/global-require (style). It requires every require() call to sit at top-level module scope. Nested requires execute lazily and possibly conditionally, hide the module's true dependency graph from tooling and readers, and push load cost into hot paths; keeping them at the top mirrors how ES import declarations are hoisted and statically visible.
Source
Thrown at crates/oxc_linter/src/rules/node/global_require.rs:12
use oxc_ast::{
AstKind,
ast::{Expression, IdentifierReference},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{AstNode, context::LintContext, rule::Rule};
fn global_require_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected require().")
.with_label(span)
.with_help("Move require() to top-level module scope")
}
#[derive(Debug, Default, Clone)]
pub struct GlobalRequire;
declare_oxc_lint!(
/// ### What it does
///
/// Require `require()` calls to be placed at top-level module scope.
///
/// ### Why is this bad?
///
/// In Node.js, module dependencies are included using the `require()` function, such as:
/// ```js
/// var fs = require("fs");
/// ```View on GitHub (pinned to e1e7af627c)
Solutions
- Hoist the require() to the top of the module next to the other requires
- For optional dependencies, require at top level and feature-detect on the result, or isolate the lazy load in a tiny wrapper module that callers require once
- Break the circular dependency by moving shared code into a third module
- If the lazy load is deliberate and profiled, silence it locally with // oxlint-disable-next-line node/global-require or scope the rule off for that directory
Example fix
// before
function getFs() {
const fs = require('fs');
return fs;
}
// after
const fs = require('fs');
function getFs() {
return fs;
} Defensive patterns
Strategy: validation
Validate before calling
// .oxlintrc.json
"rules": { "node/global-require": "error" }
npx oxlint -c .oxlintrc.json --deny-warning . Prevention
- Keep all require() calls in the module's require block at the top, mirroring how imports are hoisted in ESM
- When fighting circular dependencies, restructure modules instead of hiding requires inside functions
- For optional deps, require once at top level and branch on the result rather than requiring inside try/catch
When it happens
Trigger: A call to the bare identifier require() that is not at module top level — inside a function body, an if/try block, a loop, or a listener callback. Example trigger: function loadConfig() { const fs = require('fs'); return fs.readFileSync(p); }.
Common situations: Lazy-loading to speed up CLI startup; workarounds for circular dependencies; try/catch requires for optional dependencies; test helpers requiring fixtures per invocation; teams inheriting a strict shared oxlint config that promotes the rule from warn to error.
Related errors
- Do not mix 'require' and other declarations.
- Do not mix core, module, file and computed requires.
- Split requires to be separated into a single block.
- Unexpected access to `exports`.
- Unexpected access to `module.exports`.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/be46a0223ea07903.
Report an issue: GitHub.