ArchUnitGo

Architecture testing for Go. Write the sentence your team already says aloud and let go test show where the code disagrees. ArchUnitGo covers files, layers, slices, metrics, and dependency graphs with structured violations and no special runner.

Go 1.26+Repository terms

Go module

go get github.com/LukasNiessen/ArchUnitGo
architecture_test.go
package architecture_test

import (
    "testing"
    archunit "github.com/LukasNiessen/ArchUnitGo"
)

func TestApiDoesNotTouchDatabase(t *testing.T) {
    rule := archunit.ProjectFiles(nil).
        InFolder("internal/api/**").
        ShouldNot().DependOnFiles().
        InFolder("internal/db/**")

    archunit.AssertPasses(t, rule, nil)
}

Silent product demo

Watch an architecture rule run with go test.

This silent walkthrough follows an ArchUnitGo rule from fluent definition to test output. Playback starts muted, loops in place, and keeps standard controls available so you can pause at any step.

Watch on YouTube ↗

The ecosystem

Go, in context.

Go is a compiled language built for simple tooling, fast builds, concurrency, and maintainable network services. Packages and internal directories provide useful boundaries, while architecture tests make the intended dependency direction explicit across larger modules and workspaces.

01

Cloud services, platform tools, CLIs, and networking

02

Built-in testing with go test

03

Simple package model with fast compilation

Adoption snapshot

Public adoption, in context.

ArchUnitGo is available as a public Go module and is documented on pkg.go.dev. The Go module ecosystem does not publish package download counts.

Package status
Public Go module
No ecosystem download counter
Reported history
Unavailable
Not reported by pkg.go.dev
Latest 30 days
Unavailable
Not reported by pkg.go.dev
GitHub stars
3
Snapshot of October 4, 2026

Capabilities

What ArchUnitGo brings to the test suite.

The family shares a recognizable architecture vocabulary while each implementation stays honest about its language, toolchain, and maturity.

01

Go module and workspace discovery

02

File, named-layer, and slice rules

03

Counting and dependency metrics

04

Structured violations with test helpers

05

Graph snapshots and HTML reports

06

Glob, regex, and exclusion semantics

Go deeper

Use the test runner Go already provides.

Architecture rules are ordinary test values, so local runs and CI need no special runner. A failed policy reports structured violations through testing.T alongside the rest of the suite.

cycles_test.go
func TestInternalPackagesAreCycleFree(t *testing.T) {
    rule := archunit.ProjectFiles(nil).
        InFolder("internal/**").
        Should().HaveNoCycles()

    archunit.AssertPasses(t, rule, nil)
}

Documentation highlights

Work with ArchUnitGo beyond the quickstart.

ArchUnitGo divides every check into source discovery, language-aware extraction, language-neutral projection, pure assertion, and reporting. That boundary is also how the repository tests and explains itself.

01

Keep Go knowledge at the extraction edge

The nearest go.mod defines the project, Go analysis packages resolve imports, and build tags determine the production source set.

  • Project-relative forward-slash identifiers keep rules stable across operating systems.
  • Every file receives a self-edge so an isolated file still exists as a graph node.
  • Extraction is memoized per process and can include test files or alternate build constraints through CheckOptions.
02

Project one graph into useful questions

Files, layers, slices, metrics, and graph reports reuse the same labels and edges while adding their own selectors and violation types.

  • Layer allowlists and blocklists report one architectural relationship with the concrete imports that prove it.
  • Slice names are cut from path captures, while graph queries can focus, traverse, or collapse before rendering.
  • Checkable is the common seam: every rule returns structured violations plus a technical error separately.
03

Refuse accidental green tests

A rule selecting no files yields an EmptyTestViolation by default, and empty graph or report terminals return a named error.

  • AllowEmptyTests is an explicit opt-out when an empty scope is genuinely intended.
  • Selectors expose inspection methods so teams can see the files, layers, or slices a pattern actually matched.
  • README examples and exported identifiers are checked against source to make documentation drift testable.
Read the complete documentation ↗

Release and compatibility

Untagged preview

Functional on main with no tagged release yet; installation resolves to a pseudo-version and APIs may move.

LanguageGo
ReleaseUntagged preview
RuntimeGo 1.26+
LicenseRepository terms

Where it fits

Put boundaries next to the code they protect.

Common starting points for ArchUnitGo include the following project shapes.

Go servicesModular monolithsCLI applicationsPlatform tooling

Make the first boundary executable.

Add one meaningful rule, run it with the existing tests, and grow the architecture suite as the system reveals where it needs protection.

Start with ArchUnitGo ↗