Skip to content

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.