Usage
CLI flag reference
| Flag | Short | Default | Description |
|---|---|---|---|
paths |
. |
Paths to analyze (positional, repeatable). Accepts local paths or https:///http:///git@ GitHub/GitLab repository URLs, which are cloned into a temporary directory and cleaned up after analysis. |
|
--exclude |
-e |
Exclude patterns (comma-separated, repeatable) | |
--max-complexity-allowed |
-m |
15 |
Maximum complexity a function may have |
--quiet |
-q |
false |
Suppress per-file output |
--ignore-complexity |
-i |
false |
Do not fail the run on complexity: exit 0 even when functions exceed the threshold |
--failed |
-f |
false |
Show only functions that exceed the threshold |
--color |
-C |
auto |
Color output: auto, yes, or no |
--sort |
-s |
asc |
Sort order: asc, desc, or name |
--top |
-t |
Show only the top N results (implies desc) |
|
--plain |
false |
Machine-friendly output: one path name complexity row per function, no decorations. CLI only. |
|
--check-script |
false |
Report module-level code as a synthetic <module> function |
|
--no-ignore |
false |
Disregard all // complexijs: ignore and // noqa: complexijs markers, analyzing every function |
|
--report-ignored |
false |
Print every ignore marker found | |
--snapshot-create |
false |
Write today's offenders to complexijs-snapshot.json |
|
--snapshot-ignore |
false |
Enforce the raw threshold; ignore any existing snapshot | |
--output |
Directory (or file prefix) for report files | ||
--output-format |
Output formats: csv, json, sarif (comma-separated, repeatable) |
||
--diff |
Compare against a git ref and fail on regressions over the threshold | ||
--diff-only |
Compare against a git ref and report only, never affecting the exit code | ||
--staged |
false |
Compare the git index instead of the working tree (implies --diff HEAD) |
|
--version |
-V |
Print the version and exit |
Exit codes
| Code | Meaning |
|---|---|
0 |
Every function is within the threshold |
1 |
A function exceeds the threshold, a path was invalid, an output file could not be written, or --diff found a regression over the threshold |
2 |
Invalid configuration (for example an unknown --output-format value) |
Output formats
Plain output
--plain prints one row per function with no colors or table chrome:
path/to/file.js functionName 12
This is useful for piping into awk, grep, or a script:
complexijs . --plain | awk '$3 > 10'
File reports
Pass --output-format to write structured reports alongside the normal console output:
complexijs . --output-format json
complexijs . --output-format json,csv,sarif
complexijs . --output-format json --output reports/
Without --output, files are written as complexijs.json, complexijs.csv, and
complexijs.sarif in the invocation directory.
CSV sample (complexijs.csv):
Path,File Name,Function Name,Cognitive Complexity
src/router.js,router.js,handleRequest,17
src/utils.js,utils.js,merge,4
JSON sample (complexijs.json):
[
{
"path": "src/router.js",
"file_name": "router.js",
"function_name": "handleRequest",
"complexity": 17
},
{
"path": "src/utils.js",
"file_name": "utils.js",
"function_name": "merge",
"complexity": 4
}
]
SARIF output (complexijs.sarif) follows the SARIF 2.1.0 schema and can be uploaded to
GitHub code scanning.
Snapshot workflow
A snapshot is a watermark: it records the functions that currently exceed the threshold so an existing codebase can adopt complexijs without a mass refactor, while still blocking regressions.
complexijs . --snapshot-create # record today's offenders
complexijs . # green: recorded offenders are suppressed
Once the snapshot exists, a recorded function passes as long as its complexity does not grow. If it grows, or a new function crosses the threshold, the run fails and reports what changed:
src/monster.js:monster increased from 17 to 20.
The snapshot is stored as complexijs-snapshot.json in the invocation directory. Commit it to
version control. Use --snapshot-ignore to enforce the raw threshold and see the real state of the
code.
Complexity diff
--diff <ref> compares the functions in the current working tree against the same functions at a
git ref and prints what changed:
complexijs . --diff HEAD # against the last commit
complexijs . --diff main # against a branch
complexijs . --diff origin/main~3 # against any revision git understands
------------------------ Complexity diff (vs HEAD) ------------------------
REGRESSED src/router.js::handleRequest 12 -> 17 (+5)
IMPROVED src/utils.js::merge 9 -> 4 (-5)
NEW src/router.js::parseQuery 6 (new)
REMOVED src/legacy.js::oldPath 22 (removed)
Net: 1 regressed, 1 improved, 1 new, 1 removed
Unchanged functions are not listed. When nothing changed the diff prints
No functions changed relative to <ref>.
Ratchet semantics
--diff is a ratchet, not a freeze. It fails the run (exit 1) only when a function both got worse
and ended up over --max-complexity-allowed:
| Situation | Result |
|---|---|
| Complexity grew but stayed at or below the threshold | pass |
| Complexity grew past the threshold | fail |
| A new function is over the threshold | fail |
| A function was already over the threshold and did not grow | pass |
| Complexity dropped | pass |
That means you can adopt complexijs on a codebase with existing offenders: the diff blocks new
damage without demanding a refactor first. Use --diff-only <ref> for the same report with no
effect on the exit code, which is useful for informational CI comments.
--diff and --diff-only are mutually exclusive. Passing both prints a warning and keeps
--diff-only. The pair is read from one source at a time: passing either flag on the command line
ignores both complexijs.toml values, so a file-level diff-only cannot quietly disable a
command-line --diff.
Both modes need a git repository. Outside one, complexijs warns on stderr and skips the diff rather
than reporting every function as new. The diff also honors --check-script and --no-ignore: both
sides of the comparison are analyzed with the same flags, so revealing <module> or an ignored
function never shows up as a spurious NEW entry.
Staged workflow
--staged compares the git index (what git commit would record) instead of the working tree,
which is what a pre-commit hook wants:
complexijs . --staged # index vs HEAD
complexijs . --staged --diff main # index vs main
Without an explicit --diff/--diff-only, --staged implies --diff HEAD. Only staged source
files are considered, and the ref label reads HEAD (staged). Outside a git repository, --staged
prints a warning to stderr and skips the diff without failing the run.
Ignore comments
Put a marker on the function definition line or on the line directly above it to skip that
function. Markers are case-insensitive and work in // and /* */ comments:
// complexijs: ignore
export function legacyRouter(req, res) {
// ...
}
function alsoSkipped() {} // noqa: complexijs
--no-ignore (flag) analyzes everything, markers included. --report-ignored prints every marker
it found, so an ignore list stays reviewable. When an ignored function is in fact below the
threshold, complexijs points out that the marker can be deleted.