Cognitive Complexity — Measuring Code Understandability
Cognitive complexity measures how difficult code is for a human to understand. Unlike cyclomatic complexity, it penalizes deeply nested structures more heavily — reflecting the real mental effort needed to follow complex code.
Code Complexity Analyzer
Paste JavaScript or TypeScript code to analyze cyclomatic complexity, cognitive complexity, nesting depth, and maintainability index per function. 100% client-side — your code never leaves your browser.
How cognitive complexity differs from cyclomatic
Cyclomatic complexity treats all decision points equally — an if at the top level counts the same as an if nested 5 levels deep. Cognitive complexity adds nesting penalties: a nested if contributes more to the score than a flat one because it is genuinely harder to understand. Additionally, else if does not increment nesting (it continues a chain), while else does increment (it adds a new mental branch). This makes cognitive complexity a better proxy for human readability.
Scoring rules
Cognitive complexity increments for breaks in linear flow: if, else if, else, for, while, do, switch, catch, ternary, and logical operators (&&, ||). For nesting structures (if, for, while, do, switch, catch), a nesting penalty equal to the current nesting depth is added on top of the base increment. So a deeply nested if might add 1 (base) + 4 (nesting) = 5 to the total, while a top-level if adds just 1.
// Cognitive Complexity = 1 (flat, easy to read)
function isValid(x) {
if (x > 0) return true; // +1 (nesting 0)
return false;
}
// Cognitive Complexity = 9 (deeply nested — hard to follow)
function process(data) {
if (data) { // +1 (nesting 0)
for (const item of data) { // +2 (1 base + 1 nesting)
if (item.active) { // +3 (1 base + 2 nesting)
if (item.value > 0) { // +4 (1 base + 3 nesting) ← penalty!
handle(item); // Total: 1+2+3+4 = 10
}
}
}
}
}
// Refactored: Cognitive Complexity = 3 (guard clauses + extraction)
function process(data) {
if (!data) return; // +1
for (const item of data) { // +1
if (item.active && item.value > 0) handle(item); // +1
}
}Reducing cognitive complexity
Use guard clauses (early returns) to eliminate nesting. Extract nested blocks into well-named helper functions — the function call adds 0 cognitive complexity while the nested block it replaces may have added 5+. Replace complex boolean conditions with named boolean variables. Avoid deep callback nesting with async/await. The goal is flat, linear code that reads top-to-bottom without requiring the reader to maintain a mental stack.
Frequently Asked Questions
What is a good cognitive complexity score?
SonarSource recommends keeping cognitive complexity under 15 per function. Under 8 is easy to understand. 9-15 needs attention. Above 15 is difficult to follow and should be refactored. Above 25 is extremely hard to understand and maintain.
Why does nesting increase cognitive complexity more?
Each level of nesting requires the reader to hold more context in their mental working memory. Understanding code at nesting depth 5 means simultaneously tracking 5 conditional states. This cognitive load grows non-linearly, which the nesting penalty reflects.
Is cognitive complexity better than cyclomatic complexity?
They measure different things. Cyclomatic complexity tells you how many test cases you need (testability). Cognitive complexity tells you how hard the code is to understand (readability). Both are useful — DevBolt shows both metrics so you can identify functions that are hard to test AND hard to read.
Related Inspect Tools
XPath Tester
Test XPath expressions against XML data with real-time evaluation — select elements, filter by attributes, navigate axes, and use XPath functions
SQL Playground
Run SQL queries in your browser with a full SQLite database powered by WebAssembly — practice JOINs, CTEs, window functions, aggregations, and more
JWT Decoder
Decode and inspect JSON Web Tokens instantly
Regex Tester
Test regular expressions with real-time match highlighting