go · coupling metrics · 9 ecosystems
Package coupling & circular dependencies.
Compute Robert C. Martin's afferent (Ca) and efferent (Ce) coupling and instability, plus circular-dependency detection, across 9 ecosystems — straight from imports you already extracted. No parser required.
MIT licensed · one small dependency · Go 1.26+
g := coupling.Build(root, files) for _, c := range g.Coupling() { fmt.Printf("%-24s Ca=%d Ce=%d I=%.2f\n", c.Package, c.Afferent, c.Efferent, c.Instability) }
what you get
Coupling metrics, straight from imports.
Feed it the imports you already extracted and it builds the dependency graph, ranks the fragile hubs, and surfaces the cycles — no language parser in the loop.
Martin metrics
Afferent (Ca), efferent (Ce), and instability I = Ce/(Ca+Ce) per package — the classic Robert C. Martin coupling numbers.
Circular dependencies
Strongly-connected-component detection, with the largest cycles surfaced first so the worst tangles are the first thing you see.
9 ecosystems
Go, Rust, Swift, JVM (Java/Kotlin/Scala), C#, PHP, Perl, Python, JS/TS, C/C++ — detected from the build manifest.
No parser needed
Consumes pre-extracted imports (pairs with treesitter-symbols); it only builds the graph and computes.
Ranked for triage
Results are ordered to surface fragile hubs first — high afferent coupling, then high instability — so you know where to look.
Nearly dependency-free
One small dependency — pelletier/go-toml/v2, for reading Cargo.toml — and nothing else.
usage
Coupling numbers and cycles.
Build the graph once, then read it two ways: the per-package coupling metrics, or the circular-dependency cycles.
// Per-package coupling metrics g := coupling.Build(root, files) for _, c := range g.Coupling() { fmt.Printf("%-24s Ca=%d Ce=%d I=%.2f\n", c.Package, c.Afferent, c.Efferent, c.Instability) }
// Circular dependencies (largest first) for _, cyc := range g.Cycles() { fmt.Printf("cycle: %v\n", cyc.Nodes) }
- Go
- Rust
- Swift
- JVM
- C#
- PHP
- Perl
- Python
- JS/TS
- C/C++
install
Add it to your module.
One go get, then import it. Requires Go 1.26+.
go get github.com/richardwooding/go-coupling
import coupling "github.com/richardwooding/go-coupling"
Feed it imports extracted by treesitter-symbols, then build the graph. Full API on the Go Reference.