Arklint
The architectural rulebook for your codebase. Define structural rules in YAML and enforce them before bad code — written by AI agents or humans — ever lands.
pip install arklint
npx arklint check
dotnet tool install -g arklint
$ arklint check Arklint v0.2.0 — Scanning 142 files against 5 rules... ✗ FAIL no-direct-db-in-routes routes/users.py → imports 'sqlalchemy' — blocked routes/orders.py → imports 'psycopg2' — blocked ✗ FAIL single-http-client conflicting packages — keep one of requests, httpx ⚠ WARN no-print-statements services/email.py:45 → banned pattern: 'print(' ✓ PASS models-in-models-dir ✓ PASS layered-architecture ──────────────────────────────────────────────────── Results: 2 errors, 1 warning, 2 passed
Installation #
Arklint is available on PyPI, npm, and NuGet. All three install methods run the same binary.
Python (PyPI)
The core CLI. Requires Python 3.10+. Includes all rule types, watch mode, diff mode, and JSON output.
$ pip install arklint
For MCP server support (AI agent integration), install with the optional extra:
$ pip install 'arklint[mcp]'
For AI-powered rule generation with arklint learn:
$ pip install 'arklint[ai-anthropic]' # Claude (Anthropic) $ pip install 'arklint[ai-openai]' # GPT-4o-mini (OpenAI)
Node.js (npm)
A thin wrapper that auto-downloads the platform-specific prebuilt binary from GitHub Releases on first run. No Python needed on the machine.
# Run directly without installing $ npx arklint check # Or install globally $ npm install -g arklint $ arklint check
Supports Linux x64, macOS ARM64 (Apple Silicon), and Windows x64.
.NET (NuGet)
A .NET global tool wrapper. Also auto-downloads the prebuilt binary and caches it at ~/.arklint/bin/. Requires .NET 8.0+.
$ dotnet tool install -g arklint $ arklint check
Quick Start #
Get from install to your first architecture check in four steps.
1. Generate a starter config
Run arklint init in your project root. This creates a .arklint.yml with sensible starter rules.
$ cd ~/my-project $ arklint init
2. Edit your rules
Open .arklint.yml and tailor the rules to your architecture — import boundaries, banned patterns, layered dependencies — all in readable YAML.
"k">version: "1" "k">rules: - id: no-direct-db-in-routes "k">type: boundary "k">description: "API routes must not import database modules" "k">source: "routes/**" "k">blocked_imports: - "sqlalchemy" - "psycopg2" "k">severity: error - id: no-print-statements "k">type: pattern-ban "k">pattern: 'print\(' "k">exclude: - "tests/**" "k">severity: warning
3. Run the check
Scan your codebase. Add flags as needed:
$ arklint check $ arklint check --strict # exit 1 on warnings too $ arklint check --json # JSON output for CI $ arklint check --diff main # only scan changed files
4. Add to your workflow
- Watch mode — instant feedback as you code:
arklint watch - Pre-commit hook — block violations before they’re committed
- CI gate — fail the pipeline on violations
- GitHub Action — first-class Action with diff mode and version pinning
See CI / Pre-commit and GitHub Action for ready-to-copy configs.
Rule Types #
Arklint ships with five rule types. Each targets a specific class of architectural violation. All are language-agnostic and configured in `.arklint.yml`.
Import Restrictions
Block files in a source directory from importing specific packages. Keep API routes away from raw database drivers.
- id: no-direct-db-in-routes "k">type: boundary "k">source: "routes/**" "k">blocked_imports: - "sqlalchemy" - "psycopg2" - "pymongo" "k">severity: error
Package Conflicts
Detect when multiple libraries serving the same purpose exist in your dependency file.
- id: single-http-client "k">type: dependency "k">allow_only_one_of: - "requests" - "httpx" - "aiohttp" "k">severity: error
Code Placement
Ensure certain code patterns only exist in the right directories.
- id: models-in-models-dir "k">type: file-pattern "k">pattern: 'class\s+\w*Model' "k">allowed_in: - "models/**" - "schemas/**" "k">severity: warning
Banned Patterns
Ban any regex pattern across the codebase with optional directory exclusions.
- id: no-print-statements "k">type: pattern-ban "k">pattern: '(?<!\.)print\(' "k">exclude: - "tests/**" - "scripts/**" "k">severity: warning
Layered Architecture
Define layers and control which ones can import from which. Enforce strict dependency direction.
- id: layered-architecture "k">type: layer-boundary "k">layers: - name: routes "k">path: "routes/**" - name: services "k">path: "services/**" - name: repositories "k">path: "repositories/**" "k">allowed_dependencies: "k">routes: [services] "k">services: [repositories] "k">repositories: [] "k">severity: error
CLI Reference #
Every command and flag Arklint supports.
| Command | Description |
|---|---|
arklint init |
Generate a starter .arklint.yml in the current directory |
arklint init --force |
Overwrite an existing config file |
arklint check |
Scan the codebase from the current directory |
arklint check <path> |
Scan a specific directory |
arklint check --strict |
Exit with code 1 on warnings (not just errors) |
arklint check --quiet / -q |
Suppress passing rules — only show failures and warnings |
arklint check --json |
Machine-readable JSON output for CI pipelines |
arklint check --diff <ref> |
Only scan files changed vs a git ref |
arklint check --github-annotations |
Emit GitHub Actions inline PR annotations |
arklint check -c <path> |
Use a config file from a custom path |
arklint validate |
Validate .arklint.yml without running any checks |
arklint validate -c <path> |
Validate a config file at a custom path |
arklint export --format <fmt> |
Export rules as an AI assistant instruction file |
arklint export --output <dir> |
Write exported file to a specific directory |
arklint learn --describe <text> |
Generate a rule from a plain-English description using AI |
arklint learn --provider <name> |
AI provider: anthropic or openai (required) |
arklint learn --append |
Append suggested rule to .arklint.yml without prompting |
arklint watch |
Watch for file changes and re-run checks automatically |
arklint watch --strict |
Watch mode with strict severity |
arklint mcp |
Start the MCP server (stdio) for AI agent integration |
arklint --version |
Show version and exit |
Watch Mode #
Get instant feedback as you code. Arklint re-runs checks on every file save.
$ arklint watch $ arklint watch ./src --strict
Watch mode uses watchdog to monitor filesystem events. It automatically ignores hidden directories, __pycache__, dist, and build folders. Press Ctrl+C to stop.
Diff Mode #
Only scan files that changed — perfect for large codebases and CI on pull requests.
$ arklint check --diff HEAD # staged + unstaged changes $ arklint check --diff origin/main # changes vs main branch
Diff mode runs git diff --name-only under the hood, including both staged and unstaged changes. Only the changed files are scanned against your rules.
MCP Server #
Expose your architectural rules to AI agents via the Model Context Protocol. AI coding tools can check code before writing it.
$ pip install 'arklint[mcp]' $ arklint mcp
Available tools
- list_rules — Returns all configured rules from
.arklint.ymlwith full config details. - get_rule_details — Inspect a single rule’s full configuration by its ID.
- check_file — Validate an existing file against all rules and return violations.
- check_snippet — Validate a code snippet before writing it to disk. Supports virtual paths for path-based rules.
The check_snippet tool is especially powerful — an AI agent can validate code before committing it, using the filename parameter to control which path-based rules apply (e.g. passing routes/user.py triggers boundary rules).
Claude Code / Cursor integration
{
"mcpServers": {
"arklint": {
"command": "arklint",
"args": ["mcp"]
}
}
}
Export Rules #
Export your `.arklint.yml` rules as AI assistant instruction files so your coding tools respect the same architectural constraints.
$ arklint export --format cursorrules $ arklint export --format claude $ arklint export --format copilot
Formats
| Format | Output file | Used by |
|---|---|---|
cursorrules |
.cursorrules |
Cursor IDE |
claude |
CLAUDE.md |
Claude Code |
copilot |
.github/copilot-instructions.md |
GitHub Copilot |
Each file lists your rules with severity tags ([ERROR] / [WARN]) and descriptions in a format the AI understands natively.
Options
| Flag | Description |
|---|---|
--format / -f |
Output format (required): cursorrules, claude, or copilot |
--output / -o |
Directory to write into. Defaults to current directory |
--config / -c |
Path to .arklint.yml. Auto-discovered if omitted |
Example
$ arklint export --format claude --output .
This writes CLAUDE.md in your project root. Claude Code will automatically pick it up on the next session and respect your architectural rules when generating code.
arklint export whenever you update your rules to keep the AI instruction files in sync.AI Rule Generation #
Generate a valid `.arklint.yml` rule from a plain-English description using AI.
$ arklint learn --describe "no raw SQL queries in route handlers" --provider anthropic $ arklint learn --describe "no raw SQL queries in route handlers" --provider openai
Arklint prompts the AI with your description and the full rule schema. The AI returns a ready-to-use YAML rule block. You can review it and optionally append it to your .arklint.yml.
Installation
Install the optional AI dependency for your preferred provider:
$ pip install 'arklint[ai-anthropic]' # Claude (Anthropic) $ pip install 'arklint[ai-openai]' # GPT-4o-mini (OpenAI)
Options
| Flag | Description |
|---|---|
--describe / -d |
Plain-English description of the rule (required) |
--provider / -p |
AI provider: anthropic or openai (required) |
--api-key |
API key for the provider. Falls back to ANTHROPIC_API_KEY or OPENAI_API_KEY |
--append / -a |
Append the rule to .arklint.yml without confirmation prompt |
--config / -c |
Path to .arklint.yml. Auto-discovered if omitted |
Example session
$ arklint learn --describe "services must not import from routes" --provider anthropic Generating rule via anthropic… Suggested rule: - id: no-routes-in-services type: boundary description: Services must not import from route handlers source: "services/**" blocked_imports: - "routes" severity: error Append this rule to .arklint.yml? [y/N]: y ✓ Rule appended to /my-project/.arklint.yml Run arklint validate to confirm the config is valid.
--api-key flag and passed directly to the provider’s SDK at runtime.CI / Pre-commit #
Enforce rules automatically on every push or commit.
GitHub Actions
- name: Arklint
"k">run: |
pip install arklint
arklint check --strict
pre-commit hook
- repo: local "k">hooks: - id: arklint "k">name: arklint "k">entry: arklint check "k">language: python "k">pass_filenames: false
GitHub Action #
Use Arklint as a first-class GitHub Action with built-in diff mode, version pinning, and strict mode.
- uses: Kaushik13k/ark-lint@main "k">with: "k">strict: "true" "k">diff: "origin/main" "k">version: "0.2.0"
Inputs
| Input | Description | Default |
|---|---|---|
version |
Arklint version to install. Defaults to latest. | latest |
strict |
Treat warnings as errors. | false |
diff |
Only scan files changed vs this ref. | (empty = all files) |
config |
Path to .arklint.yml. Auto-discovered if omitted. |
(auto) |
working-directory |
Directory to run arklint in. | . |
Language Support #
Import extraction and dependency parsing across popular languages and package managers.
Import Extraction
Python, JavaScript, TypeScript, Go, Ruby, Rust, Java, C#, PHP
Dependency Files
requirements.txt, package.json, pyproject.toml, go.mod, Cargo.toml, Gemfile
Contributing #
Arklint is open source and welcomes contributions. Every change goes through a pull request.
Dev setup
$ git clone https://github.com/Kaushik13k/arklint cd arklint $ python -m venv .venv && source .venv/bin/activate $ pip install -e ".[dev]" $ pytest -v
Ground rules: every PR needs CODEOWNER approval, every source change needs a test, and all CI checks must pass. See CONTRIBUTING.md for the full guide.