We don't fix your architecture. We stop it from getting worse.
Your codebase has 47 circular dependencies. Everyone knows. Nobody has time to fix them.
And that's okay.
What's not okay is adding the 48th one in your next PR.
npx -y @archlinter/cli diff HEAD~1 --explainπ΄ REGRESSION: New cycle detected
src/orders/service.ts β src/payments/processor.ts β src/orders/service.ts
Why this is bad:
Circular dependencies create tight coupling between modules.
Changes in one module can cause unexpected failures in the other.
How to fix:
Extract shared logic into a separate module, or use dependency injection.
Exit code: 1
PR blocked. Architecture protected. Zero onboarding required.
Static analysis tools love to dump 500 issues on you and call it a day.
- SonarQube: "You have 127 code smells" β team ignores it
- ESLint: "379 warnings" β
// eslint-disable-next-line - You: "We'll fix it later" β you won't
The result? Technical debt compounds silently until refactoring becomes a 6-month project.
Archlint doesn't ask you to fix everything.
It asks you to stop making it worse.
# GitHub Actions
- name: archlint
uses: archlinter/action@v1
with:
baseline: origin/${{ github.base_ref }}
fail-on: medium
github-token: ${{ github.token }}That's it. Your PR now fails only if:
- You introduce a new architectural smell
- You worsen an existing one
Everything else passes. Your legacy code is safe. Your future code is protected.
# One command. No config. No server.
npx @archlinter/cli scan
# Save a baseline (e.g., on main branch)
npx @archlinter/cli snapshot -o .archlint-baseline.json
# Check for regressions in PR
npx @archlinter/cli diff .archlint-baseline.json| SonarQube | ESLint | Archlint | |
|---|---|---|---|
| Focus | Code smells | Syntax/style | Architecture |
| Setup | Server + DB + tokens | Config files | npx |
| Diff mode | Issues count | β | Semantic regressions |
| Explains why | Generic | β | Per-smell context |
| Blocks PRs on | New issues | Rules | Architectural drift |
Dependency Issues:
- Circular dependencies (file & type-level)
- Layer violations (domain β infra? blocked)
- Stable Dependencies Principle violations
Design Smells:
- God modules (doing too much)
- Hub modules (everything depends on it)
- Low cohesion classes (LCOM4 metric)
Code Organization:
- Dead code & unused exports
- Barrel file abuse
- High coupling
The recommended way to use archlint on GitHub is via our official GitHub Action:
name: Architecture
on: [pull_request]
jobs:
archlint:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # Required for PR comments
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Important for git diff analysis
- name: archlint
uses: archlinter/action@v1
with:
baseline: origin/${{ github.base_ref }}
fail-on: medium
github-token: ${{ github.token }}architecture:
script:
- npx @archlinter/cli diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"#!/bin/bash
npx @archlinter/cli diff HEAD~1 --fail-on highCreate .archlint.yaml for project-specific rules:
rules:
# Layer architecture enforcement
layer_violation:
layers:
- name: domain
path: '**/domain/**'
allowed_imports: []
- name: application
path: '**/application/**'
allowed_imports: ['domain']
god_module:
severity: high
fan_in: 15
fan_out: 15
high_coupling:
max_cbo: 20
# Framework-aware analysis
extends: nestjs # knows controllers are entry pointsGet architectural feedback directly in your editor:
npm install --save-dev @archlinter/eslint-plugin// eslint.config.js
import archlint from '@archlinter/eslint-plugin';
export default [archlint.configs['flat/recommended']];- ~200 files in <5s β Rust + oxc parser
- Instant re-runs β content-based caching
- Watch mode β real-time feedback during development
- Ratchet, don't renovate β lock current state, prevent degradation
- Explain, don't just report β every regression comes with context
- Zero friction β
npx, no server, no tokens, no config required - Architecture > syntax β ESLint handles style, we handle structure
- Official Documentation
- Getting Started
- Available Detectors
- Configuration Guide
- CLI Reference
- ESLint Plugin
- MCP Server
MIT β use it, fork it, make your architecture better.