oxc-project/oxc · warning · OxcDiagnostic

Barrel file detected, {total} modules are loaded which excee

Error message

Barrel file detected, {total} modules are loaded which exceeds the threshold of {threshold}.

What it means

Oxlint rule `oxc/no_barrel_file` uses the module graph to count how many modules a file pulls in via `export *` / `import *` re-exports. When that count exceeds the configured threshold, the file is flagged as a barrel: importing anything from it forces runtimes and bundlers to load and parse the entire re-exported subtree, slowing cold starts and builds.

Source

Thrown at crates/oxc_linter/src/rules/oxc/no_barrel_file.rs:14

use crate::{
    ModuleRecord,
    context::LintContext,
    module_graph_visitor::{ModuleGraphVisitorBuilder, VisitFoldWhile},
    rule::{DefaultRuleConfig, Rule},
};
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use schemars::JsonSchema;
use serde::Deserialize;

fn no_barrel_file(total: u32, threshold: u32, labels: Vec<LabeledSpan>) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "Barrel file detected, {total} modules are loaded which exceeds the threshold of {threshold}.",
    ))
    .with_help(format!("Consider importing directly from the specific modules instead of using `export *` or `import *`.\nLoading {total} modules may be slow for runtimes and bundlers."))
    .with_note("See: https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-7")
    .with_labels(labels)
}

#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoBarrelFile {
    /// The maximum number of modules that can be re-exported via `export *`
    /// before the rule is triggered.
    threshold: u32,
}

impl Default for NoBarrelFile {
    fn default() -> Self {
        Self { threshold: 100 }

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Import directly from the specific feature modules at call sites instead of the barrel
  2. Replace `export *` with explicit named re-exports limited to the public API surface
  3. Raise the threshold in `.oxlintrc.json` for known-good barrels, or disable the rule via `overrides` for that one file
  4. Split the barrel into smaller topical entry points

Example fix

// before (src/index.ts)
export * from './button';
export * from './input';
// ... 120 more modules

// after (call sites import directly)
import { Button } from './ui/button';
import { Input } from './ui/input';
Defensive patterns

Strategy: fallback

Validate before calling

// quick pre-check before adding a new export * to a barrel
count=$(rg -c "^export \*" src/index.ts || echo 0)
echo "barrel re-exports: $count"

Prevention

When it happens

Trigger: An `index.ts`/`index.js` containing many `export * from './x'` statements (or `import * as ns from './x'; export { ns }` equivalents) whose transitively reachable module count, resolved through the module graph, is greater than the rule's `maximumModules`-style threshold option.

Common situations: Component/utility libraries exporting everything from one index; monorepo package barrels that transitively re-export hundreds of modules; slow dev-server or CI cold starts traced to barrel imports.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/78c16ad3863a6b29. Report an issue: GitHub.