Local Developer Tooling
Before code reaches CI, a set of local tools runs on every commit. They’re the first line of defense for quality and consistency.
Husky
- What: Git hooks (e.g.
pre-commit) that run scripts before a commit completes. - Why: We run lint-staged, typecheck, test, contract coverage, Semgrep, and E2E in pre-commit so broken or unsafe code can’t be committed without deliberately skipping the hook. We have a project rule: don’t use
--no-verifyto bypass; fix the failure or the hook instead.
Lint-staged
- What: Runs formatters and linters only on staged files.
- Why: Fast feedback; we format and lint on save/stage so the codebase stays consistent. Config lives in
package.jsonunderlint-staged.
ESLint
- What: Linting and import-boundary enforcement for TypeScript/JavaScript.
- Why: Enforces ports/adapters boundaries, style, and project rules (e.g. no magic strings, service contracts). The assistant is instructed to run
pnpm lintand fix issues before committing.
TypeScript (typecheck)
- What:
pnpm typecheckruns the compiler in noEmit mode. - Why: Ensures the whole project type-checks. Runs in pre-commit and CI so type errors are caught early.
Commitlint
- What: Validates commit messages (e.g. Conventional Commits).
- Why: Keeps history consistent and enables tools (e.g. release notes) that depend on message format. We combine this with Linear discipline: commits reference issue keys.
Prettier / format
- What: Code formatting via Prettier (and project config in
conf/). - Why: One style across the repo; lint-staged runs format on staged files so formatting is never a reason for CI to fail.
Semgrep
- What: Static analysis for security and bug patterns.
- Why: Pre-commit runs Semgrep so obvious issues don’t get committed. CI runs
semgrep:cito fail the build on findings. The assistant is told not to suggest skipping hooks; if Semgrep flags something, we fix or adjust the rule.
Summary
Together, Husky + lint-staged + ESLint + typecheck + commitlint + format + Semgrep + E2E form a local quality gate. The same stack (plus docs build and cycle check) runs in CI. When you add a new rule or tool (e.g. a new ESLint rule), document it here or in the Reference if it’s part of the AI ecosystem (e.g. a Cursor rule that references it).