Rule
Avoid deep nesting levels.
Deep nesting makes code hard to read and understand.
Supported languages: 45+Introduction
Code with four, five, or six levels of nesting creates cognitive burden that slows down development. Each nesting level makes it harder to track active conditions, error paths, and business logic. Excessive nesting often indicates missing abstractions or opportunities to use early returns and guard clauses.
Why it matters
Code maintainability and bug risks: Deep nesting creates "arrow code" that pushes logic off screen, slowing code review. Developers miss edge cases when modifying nested code because they can't see all conditions that must be satisfied. Changes that look correct in isolation can break assumptions made several levels up.
Testing and debugging complexity: Each nesting level doubles the test cases needed for coverage, creating exponential path explosion. Stack traces from errors don't show which conditions led there, making bugs difficult to reproduce.
Code examples
❌ Non-compliant:
function processOrder(order) {
    if (order) {
        if (order.items && order.items.length > 0) {
            if (order.customer) {
                if (order.customer.address) {
                    if (order.paymentMethod) {
                        if (validatePayment(order.paymentMethod)) {
                            return submitOrder(order);
                        }
                    }
                }
            }
        }
    }
    return { error: 'Invalid order' };
}
Why it's wrong: Six levels of nesting make it difficult to see the actual business logic (order submission) buried at the bottom. Each condition check adds another layer of indentation, and the error handling is unclear because there's no indication which specific validation failed.
✅ Compliant:
function processOrder(order) {
    if (!order) {
        return { error: 'Order is required' };
    }
    if (!order.items || order.items.length === 0) {
        return { error: 'Order must contain items' };
    }
    if (!order.customer?.address) {
        return { error: 'Customer address is required' };
    }
    if (!order.paymentMethod || !validatePayment(order.paymentMethod)) {
        return { error: 'Invalid payment method' };
    }
    return submitOrder(order);
}
Why this matters: Guard clauses with early returns flatten the nesting to a single level. Each validation is explicit and returns a specific error message. The happy path (order submission) is visible at the end without any nesting. The code is self-documenting and easy to modify without breaking existing conditions.
Conclusion
Keep nesting levels to three or fewer whenever possible. Use early returns, guard clauses, and helper functions to flatten deeply nested structures. When you encounter nesting beyond three levels, it's a signal to refactor by extracting methods, inverting conditions, or rethinking the approach. Flat code is easier to read, test, debug, and maintain than deeply nested alternatives.
.avif)
