@cofferdam/cofferdam
v0.3.6
Published
TypeScript code-quality analyzer — Rust core + JS plugin layer, inspired by Elixir's Credo
Downloads
1,291
Maintainers
Readme
cofferdam
TypeScript code-quality analyzer with a Rust core. Sorts findings by priority across five categories (Consistency, Design, Readability, Refactor, Warning) and gates CI on a configurable severity axis. Inspired by Elixir's Credo.
Install
pnpm add -D @cofferdam/cofferdam # pnpm
npm install -D @cofferdam/cofferdam # npm
yarn add -D @cofferdam/cofferdam # yarnThe package downloads a pre-built binary for your platform on install (Linux x64/arm64 gnu+musl, macOS x64/arm64, Windows x64) and runs it through a tiny JS shim.
pnpm users: pnpm v10's default sandbox blocks postinstall scripts unless the package is on the allowlist.
pnpm add -D @cofferdam/cofferdamwill "succeed" without ever downloading the binary. Add this to yourpackage.jsonso the binary install actually runs:{ "pnpm": { "onlyBuiltDependencies": ["@cofferdam/cofferdam"] } }Then re-run
pnpm install(orpnpm rebuild @cofferdam/cofferdamfor an existing install). Verified you're hit by this ifpnpm exec cofferdam --versionerrors with "binary not found".
First run
pnpm exec cofferdam initinit writes three things and asks once whether to capture a baseline
of your current findings:
cofferdam.toml— every check stanza commented out so you can see what's tunable. Edit only the values you care about; defaults cover the rest..cofferdam/baseline.json— snapshot of findings the build should not fail on (your existing tech debt). Commit this file..gitignore—.cofferdam/is added with a!.cofferdam/baseline.jsonnegation, so the baseline stays tracked while future cache content is ignored.
After init:
pnpm exec cofferdam check src/ # exits 0 — everything baselinedAdd a fresh == to your code, re-run, and CI will fail with only the
new finding flagged.
Built-in checks
Cofferdam ships 20+ built-in checks across all five categories,
including project-graph rules (Design.OrphanExport,
Design.ImportCycle, Design.LayerViolation, Refactor.DeadExport)
and complexity rules (Refactor.CyclomaticComplexity,
Refactor.CognitiveComplexity). Severity gates CI; priority sorts
the report — the two are deliberately separate axes.
Full catalog with bad/good examples, options, and per-check defaults: https://tajd.github.io/cofferdam/checks/.
CI integration
GitHub Actions
- uses: actions/checkout@v6
with:
# fetch-depth: 0 so --since can resolve the base branch ref
fetch-depth: 0
- run: pnpm install --frozen-lockfile
- run: pnpm exec cofferdam check src/ --since origin/${{ github.base_ref }} --fail-on=high--since <git-ref> runs only against files changed in <ref>...HEAD,
so PR checks stay fast on large repos. --fail-on=high exits 1 only
when at least one finding is High or Critical — Medium and below
print but don't fail CI.
Husky pre-commit
# .husky/pre-commit
pnpm exec cofferdam check --since HEAD --fail-on=highConfiguration
cofferdam.toml at the project root. Discovered by walking up from the
working directory until a .git is reached. Every key is optional —
unset values fall back to the defaults.
# Lower a check's severity so it stops failing CI but still appears in reports
[checks."Refactor.CyclomaticComplexity"]
severity = "low"
# Tighten a limit
[checks."Readability.MaxLineLength"]
limit = 100Override per invocation: --config <path> points at a specific file,
--no-config skips discovery entirely.
Suppression
Inline directives let you silence a finding with an auditable reason field. Canonical form:
// cofferdam-ignore: Warning.NoEval: codegen bootstrap, not user input
eval(generatedCode);Range and file-scoped variants:
// cofferdam-ignore-start: Refactor.CyclomaticComplexity
function generatedRouter(req, res) { /* ... */ }
// cofferdam-ignore-end
// cofferdam-ignore-file: Readability.MaxLineLengthESLint-style aliases (// cofferdam-disable-next-line <CheckId>,
/* cofferdam-disable */ ... /* cofferdam-enable */) are also
recognised for ergonomic continuity. Full syntax and reason-field
rules: https://tajd.github.io/cofferdam/suppression/.
Custom checks
Author project-specific checks in TypeScript with
@cofferdam/check-sdk.
The defineCheck API gives you AST and line views over the same
sources cofferdam already parsed; the cofferdam binary spawns a Node
host and merges your findings into its stream. Plugin authoring guide:
https://tajd.github.io/cofferdam/plugin-sdk/ (in progress).
Architectural specs
Pin the shape of your codebase in cofferdam.invariants.toml —
declare layer boundaries (ui cannot import db), freeze a public
surface (packages/sdk exports may not change without a deliberate
update), and let Design.LayerViolation and Design.BoundaryFrozen
fail CI on drift. Spec reference:
https://tajd.github.io/cofferdam/invariants/.
Exit codes
| Code | Meaning |
|------|---------|
| 0 | No findings at or above --fail-on (default: medium). Baselined findings never trigger the gate. |
| 1 | At least one finding triggers the gate. |
| 2 | Invocation, IO, or config error. |
Sandboxed installs / --ignore-scripts
If your installer disables postinstall scripts, the binary won't be downloaded. Two recovery paths:
- Manual binary — download the release archive from
GitHub Releases,
extract it, set
COFFERDAM_BINARY_PATHto the binary, thennpm rebuild @cofferdam/cofferdam. - Pre-baked image — set
COFFERDAM_SKIP_DOWNLOAD=1if the binary is already atnode_modules/@cofferdam/cofferdam/bin/cofferdam(orcofferdam.exeon Windows).
Windows + npm 6: bare
npx cofferdamfalls back tonpm runand fails withMissing script: 'cofferdam'. Usenpx -p @cofferdam/cofferdam cofferdam,pnpm exec cofferdam, or.\node_modules\.bin\cofferdam.cmd, or upgrade to npm ≥ 7.
Versioning
The npm package version tracks the cofferdam release version.
@cofferdam/[email protected] downloads the binary from the v0.2.3
GitHub Release. Lockfile-pinned installs are deterministic. The Rust
workspace and the @cofferdam/cofferdam + @cofferdam/check-sdk npm
packages are released in lockstep — an @cofferdam/[email protected]
install always pairs with an SDK at the same X.Y.Z.
License
MIT. Full source and project documentation: github.com/TAJD/cofferdam.
