Skip to content
go-coupling

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+

coupling.go
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 go get github.com/richardwooding/go-coupling
import import coupling "github.com/richardwooding/go-coupling"

Feed it imports extracted by treesitter-symbols, then build the graph. Full API on the Go Reference.