go-cmp

A safer, more powerful alternative to reflect.DeepEqual for comparing Go values in tests.

Library
Go
vv0.7.0
4,681 stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
47 /100 Fair
Development Activity 12
Maintenance 20
Community 56
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
83 /100 Excellent
Architecture 88
Code Quality 85
Innovation 78
Learning Curve 80

go-cmp is Google’s package for determining equality between Go values in test code. It exposes cmp.Equal, which recursively walks both values via reflection, and cmp.Diff, which produces a structured, human-readable report of exactly what differs, down to the specific struct field, slice index, or map key, rather than reflect.DeepEqual’s flat true/false result. Unlike reflect.DeepEqual, go-cmp panics rather than silently comparing unexported fields, forcing developers to explicitly opt in via an Ignore option or the Exporter option, which avoids a common class of false-positive test passes.

Comparison behavior is customizable through a small, composable Option system: Ignore, Comparer, and Transformer values can be scoped to specific paths or types using FilterPath and FilterValues, and the companion cmp/cmpopts package supplies ready-made options for common needs like approximate float equality, ignoring generated fields, or sorting slices before comparison. The package intentionally trades runtime performance for correctness and clarity, documenting itself as unsuitable for production code paths, making it a standard dependency in Go test suites across the ecosystem, including much of Google’s own internal and open-source Go code.

What You Get

  • A drop-in cmp.Equal/cmp.Diff pair with the identical signature so tests can switch between a boolean check and a full diff without rewriting comparison logic.
  • A composable Option system (Ignore, Comparer, Transformer, FilterPath, FilterValues) for precisely scoping custom equality rules.
  • The cmp/cmpopts sub-package with dozens of pre-built options for common cases (approximate floats, ignoring fields, sorting slices, equating empty collections).
  • Zero third-party dependencies, built entirely on the Go standard library, so it adds no supply-chain surface to a project.

Common Use Cases

  • Replacing reflect.DeepEqual in existing Go test suites to get readable diff output on failures.
  • Comparing structs containing unexported fields safely, without panics from reflect.DeepEqual’s naive unsafe access.
  • Writing custom comparison logic for domain types, such as treating two timestamps within a tolerance as equal.
  • Diffing nested collections (slices of structs, maps of slices) in integration or golden-file tests.

Under The Hood

Architecture

The package is organized around cmp.Equal/cmp.Diff entry points in compare.go, which drive a recursive comparison state machine that walks a value tree via reflection, tracking a Path (path.go) of PathStep operations (StructField, SliceIndex, MapIndex, Indirect, TypeAssertion, Transform) to describe how it reached each sub-value. Options (options.go) form a small interpreter: Option values (Ignore, Comparer, Transformer) are composed with filters (FilterPath, FilterValues) and resolved via a filter method that narrows to the single applicable option before apply mutates the traversal state. Diff reporting is a separate concern layered on top: report.go, report_compare.go, report_reflect.go, report_slices.go, and report_text.go implement a defaultReporter that builds a tree of valueNodes during comparison and lazily transforms it into a textNode tree only when .String() is called, keeping the hot comparison path free of string-building overhead. The internal/diff, internal/function, and internal/value packages isolate low-level diffing algorithms, function-signature reflection, and sortable value helpers from the public API, so the exported surface stays small and stable while the traversal and formatting machinery can evolve independently.

Tech Stack

Zero third-party dependencies: go.mod declares only the module path and a Go version constraint, with the entire implementation built on the standard library’s reflect, fmt, strings, regexp, unicode, and unicode/utf8 packages. There is no build tooling beyond go build and go test; CI runs the standard Go toolchain. The public surface is split across the root cmp package (comparison engine, options, path tracking, diff reporting) and the cmp/cmpopts sub-package, which layers convenience option constructors on top of the core Option interface without needing its own dependencies. No database, network, or deployment concerns apply; it is a pure in-process comparison library consumed via go get.

Code Quality

Testing is extensive and idiomatic table-driven Go: compare_test.go, options_test.go, cmpopts/util_test.go, and multiple example_test.go/example_reporter_test.go files exercise both Equal/Diff behavior and documented Example functions that double as executable documentation via Output comments, verified in CI on every push. Error handling favors explicit panics over swallowed errors; the package intentionally panics on ambiguous option sets or invalid comparisons, since it is designed for test code where a loud failure beats a silent false positive. Naming is consistent and exported identifiers carry full godoc comments with cross-references. No dedicated linter config was found in the repo beyond standard gofmt/go vet conventions, but the low open-issue count relative to project age and Google’s stewardship suggest a high bar for merged code.

API Design The package’s core ergonomic win is that cmp.Equal and cmp.Diff share the exact same signature and option system, so a developer writes one set of Option values and can freely switch between a boolean check and a human-readable diff without restructuring test code. The Option interface itself is a composable mini-DSL: Ignore, Comparer, and Transformer combine with FilterPath and FilterValues to scope custom equality logic precisely, and cmpopts supplies a large library of pre-built options so common cases need zero boilerplate. Diff output is genuinely differentiated: rather than a flat line-by-line diff, it produces a structured, indented tree showing exactly which nested field, slice index, or map key changed, which is far more actionable for debugging test failures on deeply nested structs than reflect.DeepEqual’s boolean-only result. It does not invent a new comparison paradigm; it is a well-executed synthesis of reflection-based equality plus a Go-idiomatic options pattern, making it a polished design rather than something conceptually novel.

Used by 29 apps in this directory

Go
97%
Apache 2.0

kopia

File Storage

14,417

Fast, encrypted, deduplicated backups to any cloud or local storage with full client-side control.

View details
90
Repo Health
83
Technical
68
Dependency
Built with
Go 97%
Updated 1 weeks ago
Go
97%
MIT

Formance Ledger

Databases · Developer Tools · Invoicing Finance

1,448

The programmable open source core ledger for fintech — build money-moving applications with atomic multi-posting transactions, account-based modeling, and Numscript, a built-in DSL for financial logic.

View details
91
Repo Health
8
Technical
68
Dependency
Built with
Go 97%
Updated 6 days ago
Go
95%
Other

NetBird

Security

30,175

Replace your VPN with a zero-trust WireGuard overlay network that auto-connects devices, enforces SSO and posture checks, and deploys in under 5 minutes.

View details
92
Repo Health
82
Technical
66
Dependency
Built with
Go 95%
Updated 6 days ago
Go
97%
Other

Netmaker

Automation · Security

11,836

Automate secure WireGuard mesh networks from homelab to enterprise scale without manual configuration.

View details
92
Repo Health
79
Technical
70
Dependency
Built with
Go 97%
Updated 1 weeks ago
Go
72%
MIT

Ollama

AI Development · Developer Tools

184,509

Run Llama, Gemma, DeepSeek, and other open LLMs on your own machine with one command and an OpenAI-compatible API.

View details
92
Repo Health
85
Technical
67
Dependency
Built with
Go 72%
C 19%
Updated 1 weeks ago
Go
52%
Apache 2.0

opencloud

File Storage

6,218

Open source file management and collaboration platform that keeps your data under your control, no database required.

View details
86
Repo Health
80
Technical
68
Dependency
Built with
Go 52%
Gherkin 33%
PHP 11%
Updated 1 weeks ago
Go
71%
Apache 2.0

OSV.dev

Security

3,001

Google's open-source vulnerability database that maps CVEs to exact package versions across 50+ ecosystems with a public API and data dumps.

View details
87
Repo Health
82
Technical
66
Dependency
Built with
Go 71%
Python 19%
Updated 1 weeks ago
Go
93%
MIT

Plandex

AI Code Assistants

15,777

An open-source, terminal-based AI coding agent built for large tasks and real codebases — with its own version control for plans, a 2M-token effective context window, and self-hosted or cloud deployment.

View details
50
Repo Health
70
Technical
67
Dependency
Built with
Go 93%
Updated 1 years ago
TypeScript
51%
ZLIB

Portainer

Devops

38,707

A lightweight, open-source web UI that puts Docker, Kubernetes, and Podman management within reach of any team—no CLI expertise required.

View details
93
Repo Health
79
Technical
65
Dependency
Built with
TypeScript 51%
Go 38%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers