arch-lint
Architecture diagrams and conventions are useful, but they drift when nothing checks them. arch-lint makes package-boundary rules executable: a YAML specification selects packages, forbids dependency patterns, and records narrowly scoped exceptions or exemptions.
Glob captures move arch-lint beyond a simple deny list. A rule can capture the module owning an imported internal package, then exempt only the facade, queries, handlers, and implementation packages belonging to that same module. Another capture can keep every concrete presentation surface private to its domain and surface kind without naming CLI, TUI, or GUI individually. Mixology also captures presentation names to keep sibling toolkits independent and permit each surface to import only its matching toolkit, while a composition rule keeps every surface out of main/**. Ownership rules make another domain’s authorization package private and restrict command implementations to their own event contracts without closing public models, queries, or events. Adding a future surface and toolkit pair does not require copying an asymmetric rule. The same analyzer can run as a command, through Go’s analysis framework, or as a golangci-lint module plugin, so the constraint can live in both local feedback and CI.
Why it is worth exploring
- It demonstrates architecture as an automatically tested property of a repository.
- Its pattern language balances broad rules with explicit, reviewable exceptions.
- It is used by the Mixology modular-monolith sample, showing the rules at work in a real codebase.
Read the configuration schema and matcher first, then see .arch-lint.yaml in go-modular-monolith for a real rule set.