AI output alignment checker — enforce your design system and architectural contracts with plain JavaScript rules.
chekr is a pipeline step between AI-generated code and commit. It catches violations ESLint cannot: raw design tokens, wrong component usage, import boundaries, and project-specific patterns.
AI generates code
→ ESLint syntax & style
→ chekr design & architecture contract ← this tool
→ Tests behavior
→ Commit
npm install -g @chekr/cli
# or as a dev dependency
npm install -D @chekr/cliRequires Node.js 18+.
# Scaffold rules and config in your project
chekr init
# Run all checks
chekr run
# Only changed files (git)
chekr run --changed
# JSON report for CI
chekr run --reporter json --report ./chekr-report.jsonYour project layout:
your-app/
chekr.config.js # optional — sensible defaults without it
.chekr/
checks/
check_raw_colors.js # your rules
check_raw_sizes.js
fixes/
fix_raw_sizes.js # optional auto-fixers
// .chekr/checks/check_raw_colors.js
export function checkRawColors(source, filePath) {
const violations = [];
for (const [i, line] of source.split("\n").entries()) {
if (/#[0-9a-fA-F]{6}/.test(line)) {
violations.push({
file: filePath,
line: i + 1,
text: line.trim(),
message: "Raw hex color — use a design token",
});
}
}
return violations;
}// chekr.config.js
/** @type {import('chekr').ChekrConfig} */
export default {
checksDir: "./.chekr/checks",
gitignore: ".gitignore",
ignoreMarker: "@chekr-ignore",
steps: [
{ id: "check_raw_colors", step: 1 },
{ id: "check_raw_sizes", step: 2 },
],
};Install types for editor support: npm install -D @chekr/types
A step can declare nested checks using existing checker IDs. Children inherit selected
file-selection and runtime fields (include, exclude, extensions, scope, and
related settings); child values override inherited values. Fields such as optimize
are intentionally not inherited.
steps: [{
id: "check_architecture",
extensions: [".js", ".ts"],
subCheckers: [
{ id: "check_import_boundaries" },
{ id: "check_layer_names", scope: ["src"] },
],
}]By default the parent runs first, followed by children in declaration order. Set
parallel_family: true on the parent to start the complete family together; all
members settle and their violations are aggregated. Reports retain each child ID,
its parentId, and nested progress context.
See the complete sub-checker families guide for execution, inheritance, validation, caching, and reporter details.
Suppress a matching step on one line with // @chekr-ignore <selector>:
const color = '#5B8FF9' // @chekr-ignore check_raw_colors
const anything = value // @chekr-ignore allSelectors can be step IDs, positive step numbers, all, or comma/space-separated combinations. Legacy @chekr-ignore-start and @chekr-ignore-end blocks still work but are deprecated and report migration warnings.
chekr provides a relational reporting system that allows rules to report complex, multi-file violations with deep context.
export function myCheck(source, filePath, context) {
// Use the report hook for high flexibility
context.report({
message: "Architectural violation",
impact: "This increases bundle size and coupling",
severity: "error",
logicalId: "arch:boundary", // Group multiple violations together
data: { customField: "metadata" },
occurrences: [
{ file: "other_file.ts", context: "Related code found here" }
]
});
}| Command | Description |
|---|---|
chekr run |
Run checks (default command) |
chekr list |
List discovered rules |
chekr validate |
Validate rule file contracts |
chekr init |
Create .chekr/ scaffold |
chekr publish |
Publish rule to Marketplace |
chekr install |
Install rule from Marketplace |
chekr analyze |
Show run history & analysis |
chekr fix |
Auto-fixers (planned) |
Common flags: --changed, --staged, --no-bail, --skip, --only, --gitignore, --reporter json.
See CLI reference.
Only two packages are published to npm:
| Package | Install | Purpose |
|---|---|---|
@chekr/cli |
npm i -D @chekr/cli |
chekr command + bundled engine & rule utilities |
@chekr/types |
npm i -D @chekr/types |
TypeScript definitions for chekr.config.js |
Installing @chekr/cli also places @chekr/core, @chekr/helpers, and @chekr/utils in node_modules (bundled, not separate registry packages). Rule files can import from @chekr/utils as documented.
import { run } from "@chekr/cli/engine";
const result = await run({
cwd: process.cwd(),
bail: false,
reporter: "json",
});
console.log(result.passed, result.violations.length);| Doc | Audience |
|---|---|
| Configuration | chekr.config.js, per-step overrides, gitignore |
| CLI | Commands and flags |
| Rule authoring | Writing checks and fixes |
| Marketplace | Publishing and installing rules |
| Analysis | Historical metrics and performance |
| Publishing | First npm publish |
| Contributing | Development setup |
Internal specs: docs/internal/
examples/minimal/— smallest working projectexamples/symphony-rules/— advanced rules (reference only)
ESLint excels at syntax and universal style. chekr excels at your contract — token names, component hierarchies, folder import rules — in ~20 lines of plain JS per rule, without AST plugin boilerplate.
MIT — see LICENSE.