Cyclomatic and cognitive complexity rules for oxlint with actionable error messages. Also available as a standalone library for programmatic complexity analysis.
Features:
- Cyclomatic and cognitive complexity analysis.
- Actionable error messages with complexity breakdown.
- Programmatic API for custom tooling
- Framework support: React, Vue, Angular, Svelte, Astro, Solid, Qwik
- File types:
.js.mjs.cjs.ts.tsx.jsx.vue.svelte.astro
Note: Refactoring tips require cognitive complexity (only it tracks nesting depth).
npm install oxlint-plugin-complexity --save-dev// .oxlintrc.json
{
"jsPlugins": ["oxlint-plugin-complexity"],
"rules": {
"complexity/complexity": [
"error",
{
"cyclomatic": 20,
"cognitive": 15
}
]
}
}Error messages show a summary, line-by-line breakdown, and refactoring tips for deep nesting:
complexity(complexity): Function 'processData' has Cognitive Complexity of 15.
Maximum allowed is 10. [if: +14, for: +1]
Breakdown:
Line 2: +1 for 'for'
Line 3: +2 for 'if' (incl. +1 nesting)
Line 4: +3 for 'if' (incl. +2 nesting)
Line 5: +4 for 'if' (incl. +3 nesting)
>>> Line 6: +5 for 'if' (incl. +4 nesting) [top offender]
↳ Tip: Extract inner loops into helper functions - each extraction removes one nesting level
function processData(items, mode, config) {
for (const item of items) {
// Line 2: +1
if (item.active) {
// Line 3: +2 (nesting=1)
if (mode === 'strict') {
// Line 4: +3 (nesting=2)
if (config.validate) {
// Line 5: +4 (nesting=3)
if (item.required) {
// Line 6: +5 (nesting=4) <- top offender
}
}
}
}
}
}Counts decision points in code. Learn more
+1 for: if, for, for...in, for...of, while, do...while, case, catch, ? :, &&, ||, ??
Measures how difficult code is to understand by penalizing nesting. Learn more
- +1 for:
if/for/while/switch/catch/? :(+nesting),else, logical sequence changes, nested functions, recursion - Excluded: React components (PascalCase + returns JSX), default value patterns (
a || [])
Detects common complexity patterns and provides actionable tips:
- Deep nesting (
nestingTipThreshold): Suggests extracting inner loops/conditions - Long else-if chains (
elseIfChainThreshold): Recommends lookup tables or strategy pattern - Logical operator sequences (
logicalOperatorThreshold): Suggests extracting boolean expressions
Analyzes variable flow to identify extractable code blocks (enabled by default, disable with enableExtraction: false):
Example output:
Smart extraction suggestions:
Lines 9-22: Extractable with some refactoring
Complexity: +11 (55% of total)
Inputs: order, config, processedItems
Suggested: processOrder(order, config, processedItems): void
Lines 25-33: Requires significant refactoring
Complexity: +6 (30% of total)
Inputs: config, totalCount, processedItems
Issue: Mutates external variable 'totalCount' (line 27)
Suggestion: Consider returning 'totalCount' instead of mutating it
TypeScript support: Preserves type annotations in suggested signatures:
Inputs: config: Config, results: number[]
Suggested: processBlock(config: Config, results: number[]): void
Extraction suggestions use static analysis heuristics and may miss:
- Globals/module variables (not tracked by variable flow analysis)
- Complex flows (closures, dynamic properties, indirect mutations)
Always review suggestions before applying, even when marked "high confidence".
Replace the removed max-cyclomatic / max-cognitive rules with the combined complexity rule:
// .oxlintrc.json
{
"jsPlugins": ["oxlint-plugin-complexity"],
"rules": {
- "complexity/max-cyclomatic": ["error", { "max": 20 }],
- "complexity/max-cognitive": ["error", { "max": 15 }]
+ "complexity/complexity": ["error", {
+ "cyclomatic": 20,
+ "cognitive": 15
+ }]
}
}The cognitive complexity metric is based on G. Ann Campbell's specification (SonarSource, 2016).
MIT
{ "complexity/complexity": [ "error", { // Complexity thresholds "cyclomatic": 20, // Default: 20 "cognitive": 15, // Default: 15 // Performance optimization (optional) "minLines": 10, // Default: 10 (skip functions <10 lines like getters; 0 = analyze all; counts comments/blanks) // Extraction suggestions (optional) "enableExtraction": true, // Default: true "extractionMultiplier": 1.5, // Default: 1.5 (triggers at 1.5× cognitive threshold) "minExtractionPercentage": 30, // Default: 30 (min % of total complexity to suggest) // Refactoring tip thresholds (optional, set to 0 to disable) "nestingTipThreshold": 3, // Default: 3 "elseIfChainThreshold": 4, // Default: 4 "logicalOperatorThreshold": 3, // Default: 3 }, ], }