Or: How we prevented architectural debt before it even happened
- SonarQube catches bugs & code smells
- Code review catches design decisions
- Nothing catches architectural violations ← this gap exists
- architect-linter fills this gap
- Free, open source, multi-language
The Problem: The Architecture Gap
Let me paint a picture you might recognize.
You have a team of developers. Maybe 10, maybe 100. You've planned a beautiful architecture:
┌─────────────────────────────────────┐
│ Presentation Layer │
│ (Components, Controllers, Pages) │
└──────────────────┬──────────────────┘
│ (through services)
┌──────────────────▼──────────────────┐
│ Service Layer │
│ (Business Logic, Domain Logic) │
└──────────────────┬──────────────────┘
│ (through repositories)
┌──────────────────▼──────────────────┐
│ Data Access Layer │
│ (Repositories, Queries, DB) │
└─────────────────────────────────────┘
Beautiful. Clean. Maintainable.
Then month 2 happens.
A component directly imports from the database layer "just this once."
A service calls another service that hasn't been created yet.
A utility function imports from the presentation layer.
Month 3? You don't have an architecture anymore. You have... spaghetti.
Why This Happens
SonarQube catches:
- ✅ Code smells (naming, complexity, duplicates)
- ✅ Bugs (null references, logic errors)
- ✅ Security issues (SQL injection, XSS)
- ❌ Architectural violations (layers crossed, bad imports)
Code Review catches:
- ✅ Design decisions
- ✅ Algorithm choice
- ✅ Function complexity
- ❌ Systematic architectural patterns (too slow to enforce manually)
The Gap:
- 100 imports per PR
- You check... maybe 5?
- 95 could violate architecture
- Human reviewer can't check them all
The Solution: architect-linter
Enter architect-linter. A linter specifically for architecture.
Think ESLint (which catches code style), but for your system design.
$ architect-linter-pro --check
❌ src/components/Button.tsx imports from src/api/user.ts
Rule violation: Presentation layer cannot import from API layer
Suggestion: Use src/services/UserService instead
❌ src/services/Auth.ts imports from src/components/LoginForm.tsx
Rule violation: Service layer cannot import from Presentation layer
✅ Rest of architecture is clean
How It Works
- Define rules in architect.json:
{
"architecture_pattern": "Hexagonal",
"forbidden_imports": [
{
"from": "src/presentation/**",
"to": "src/infrastructure/**",
"reason": "Presentation shouldn't depend on infrastructure details"
},
{
"from": "src/application/**",
"to": "src/infrastructure/**",
"reason": "Application layer is infrastructure-agnostic"
}
]
}
- Run in CI/CD:
# .github/workflows/architecture.yml
- name: Check Architecture
run: architect --check
- Get violations before merge:
❌ PR blocked: Architecture violations detected
- 2 violations found
- Fix before merging
Multi-Language Magic
Unlike ESLint (JS only) or Pylint (Python only), architect-linter works across 4 languages:
- TypeScript/JavaScript (ES6 imports)
- Python (import/from syntax)
- PHP (use statements)
- All in the same codebase
Perfect for monorepos with mixed stacks:
frontend/ (TypeScript + React)
backend/ (Python + FastAPI)
services/ (PHP + Laravel)
↓
architect-linter enforces SAME rules across all 3
Real Results
Before architect-linter:
- ⚠️ 40% of PRs rejected for architecture
- ⚠️ Code review took 30 minutes per PR
- ⚠️ Junior devs didn't understand implicit rules
- ⚠️ Architecture debt accumulated slowly
After architect-linter (2 months):
- ✅ 5% of PRs rejected (mostly legitimate design changes)
- ✅ Code review takes 5 minutes (humans focus on logic)
- ✅ New devs self-correct with CI feedback
- ✅ Zero new architectural violations
When to Use Each Tool
| Need | Tool | Why |
|---|---|---|
| Catch bugs | SonarQube | Finds logic errors, security issues |
| Review logic | Code Review | Humans are best here |
| Enforce architecture | architect-linter | Automatic, systematic, consistent |
| All together | All 3 | SonarQube + architect-linter in CI, code review for design |
Getting Started
Install
cargo install architect-linter-pro
Initialize
architect-linter-pro --init
# Interactive wizard creates architect.json
Run
architect-linter-pro --check
CI/CD Integration
# GitHub Actions
- run: architect-linter-pro --check
# GitLab CI
script:
- architect-linter-pro --check
# Pre-commit hook
# .pre-commit-config.yaml
- repo: https://github.com/sergiogswv/architect-linter-pro
rev: v5.0.0
hooks:
- id: architect-linter-pro
Comparison: architect-linter vs Alternatives
| Feature | architect-linter | ESLint | SonarQube | Manual Review |
|---|---|---|---|---|
| Multi-language | ✅ Yes | ❌ JS only | ✅ Yes | ✅ Yes |
| Architecture rules | ✅ Yes | ❌ No | ⚠️ Limited | ✅ Yes |
| Fast | ✅ Rust, parallel | ✅ JS | ❌ Slow | ❌ Very slow |
| Free | ✅ Open source | ✅ Open source | ❌ $10k+/year | ✅ Yes |
| Easy setup | ✅ 5 min | ✅ 5 min | ❌ 2 hours | N/A |
| Automation level | ✅ 100% | ✅ 100% | ✅ 90% | ❌ 0% |
Try It Now
cargo install architect-linter-pro
architect-linter-pro --init
architect-linter-pro --check
Takes 5 minutes. Your architecture will thank you.
Questions?
- 🐙 GitHub: https://github.com/sergiogswv/architect-linter-pro
- 📖 Docs: https://architect-linter-pro.dev
- 🎯 Crates.io: https://crates.io/crates/architect-linter-pro
Let me know what you think!
Top comments (0)