oxc-project/oxc · warning · OxcDiagnostic
JSX nesting depth of {depth} exceeds the configured maximum
Error message
JSX nesting depth of {depth} exceeds the configured maximum of {max} What it means
Diagnostic from react/jsx-max-depth (category: style). It reports when the JSX nesting depth of an element exceeds the configured maximum: the rule walks from each leaf JSX element/fragment, counting ancestor depth plus child depth, and even resolves through function components (it tracks visited SymbolIds so a component rendered as <Foo/> contributes the JSX depth of Foo's own tree). This implementation defaults max to 2 (see impl Default for JsxMaxDepthConfig), stricter than eslint-plugin-react's default of 4.
Source
Thrown at crates/oxc_linter/src/rules/react/jsx_max_depth.rs:21
use oxc_ast::{
AstKind,
ast::{Expression, JSXChild},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::SymbolId;
use oxc_span::{GetSpan, Span};
use rustc_hash::FxHashSet;
use crate::{
AstNode,
context::{ContextHost, LintContext},
rule::{DefaultRuleConfig, Rule},
};
fn jsx_max_depth_diagnostic(depth: u32, max: u32, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"JSX nesting depth of {depth} exceeds the configured maximum of {max}"
))
.with_label(span)
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct JsxMaxDepth(Box<JsxMaxDepthConfig>);
impl std::ops::Deref for JsxMaxDepth {
type Target = JsxMaxDepthConfig;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]View on GitHub (pinned to e1e7af627c)
Solutions
- Extract deeply nested inner JSX into child components to flatten the tree
- Raise the limit in .oxlintrc.json if the team agrees on a larger budget: { "rules": { "react/jsx-max-depth": ["warn", { "max": 4 }] } }
- Replace wrapper divs that exist only for layout with CSS (flex/grid gap, container queries) to remove DOM levels
- Disable the rule for a file with an oxlint-disable comment while a large component is being refactored
Example fix
// before (max: 2, depth 4) const Component = () => ( <div><div><div><span /></div></div></div> ); // after (depth 2) const Inner = () => <div><span /></div>; const Component = () => <div><Inner /></div>;
Defensive patterns
Strategy: validation
Validate before calling
npx oxlint -D react/jsx-max-depth src/ # then review the deepest offenders
Prevention
- Decompose deep JSX into child components as you build, not after the depth alarm fires
- Set an explicit max in .oxlintrc.json that matches the team's budget (this implementation defaults to 2, stricter than the ESLint plugin's 4)
- Remember depth crosses component boundaries — the rule counts nested function-component trees too
When it happens
Trigger: Running oxlint with react/jsx-max-depth enabled on JSX nested deeper than max (default 2): three or more levels of nested elements/fragments such as <div><div><div><span/></div></div></div> (depth 4 > 2). Depth counts elements and fragments and crosses component boundaries, so <Layout><Page><Card/></Page></Layout> adds the internal trees of Layout and Page too.
Common situations: Adopting oxlint with the rule's default max: 2 and hitting it immediately on previously-clean deep markup; migrating from eslint-plugin-react where max defaulted to 4; layout-heavy pages (page > section > card > row > cell) that were never decomposed.
Related errors
- `button` elements must have an explicit `type` attribute.
- `button` elements must have a valid `type` attribute.
- `checked` should be used with either `onChange` or `readOnly
- Use either `checked` or `defaultChecked`, but not both.
- Component definition is missing display name.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/7508326fd37872c6.
Report an issue: GitHub.