jsx-max-depth
jsx-max-depth rule
Keywords: React, JSX nesting, component depth, complexity, refactoring, ESLint rule, LLM-optimized
Limits the maximum depth of JSX nesting to encourage component extraction and improve readability. This rule is part of eslint-plugin-react-features and provides LLM-optimized error messages.
Quick Summary
| Aspect | Details |
|---|---|
| Severity | Warning (code complexity) |
| Auto-Fix | ❌ No (requires component extraction) |
| Category | React |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | Maintaining readable components, encouraging composition |
Rule Details
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 📖 Readability | Hard to follow nested JSX | Extract to child components |
| 🧪 Testability | Large components hard to test | Smaller, focused components |
| 🔄 Reusability | Nested JSX can't be reused | Create reusable components |
| 🐛 Debugging | Deeply nested errors hard to find | Isolated component logic |
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
max | number | 5 | Maximum allowed JSX nesting depth |
Examples
❌ Incorrect (with max: 3)
Awaiting a tested example. The previous snippet was removed because the rule does not behave as the doc claimed; track the regression in
benchmarks/FP_FN_REMEDIATION_TRACKER.md.
✅ Correct (with max: 3)
// Extracted component reduces depth
function ArticleContent() {
return <p>Content</p>;
}
function Article() {
return (
<article>
<ArticleContent />
</article>
);
}
function ShallowComponent() {
return (
<div> {/* depth 1 */}
<section> {/* depth 2 */}
<Article /> {/* depth 3 - component boundary */}
</section>
</div>
);
}Configuration Examples
Default (max: 5)
{
rules: {
'react-features/jsx-max-depth': 'warn'
}
}Strict (max: 3)
{
rules: {
'react-features/jsx-max-depth': ['error', { max: 3 }]
}
}Lenient (max: 7)
{
rules: {
'react-features/jsx-max-depth': ['warn', { max: 7 }]
}
}Refactoring Strategy
| Depth Level | Recommended Action |
|---|---|
| 1-3 | ✅ Good - readable structure |
| 4-5 | ⚠️ Consider extracting reusable parts |
| 6+ | 🔴 Extract into child components |
Before Refactoring
function Dashboard() {
return (
<div className="dashboard">
<header>
<nav>
<ul>
<li>
<a href="/">Home</a> {/* depth 5 */}
</li>
</ul>
</nav>
</header>
</div>
);
}After Refactoring
function NavLink({ href, children }) {
return <li><a href={href}>{children}</a></li>;
}
function Navigation() {
return (
<nav>
<ul>
<NavLink href="/">Home</NavLink>
</ul>
</nav>
);
}
function Dashboard() {
return (
<div className="dashboard">
<header>
<Navigation />
</header>
</div>
);
}Related Rules
no-multi-comp- One component per filecognitive-complexity- Limit code complexity
Further Reading
- Thinking in React - Component composition
- Component Composition - React patterns
- ESLint MCP Setup - Enable AI assistant integration
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Dynamic Variable References
Why: Static analysis cannot trace values stored in variables or passed through function parameters.
// ❌ NOT DETECTED - Prop from variable
const propValue = computedValue;
<Component prop={propValue} /> // Computation not analyzedMitigation: Implement runtime validation and review code manually. Consider using TypeScript branded types for validated inputs.
Imported Values
Why: When values come from imports, the rule cannot analyze their origin or construction.
// ❌ NOT DETECTED - Value from import
import { getValue } from './helpers';
processValue(getValue()); // Cross-file not trackedMitigation: Ensure imported values follow the same constraints. Use TypeScript for type safety.