
diffyml: structural YAML diff that speaks Kubernetes
diffyml (v1.6.2, 51★, Go, MIT) replaces the noisy line-by-line output of `kubectl diff` with structured, key-path-grouped YAML comparisons. It identifies Kubernetes resources by identity (apiVersion + kind + metadata.name), detects renames, and fits natively into KUBECTL_EXTERNAL_DIFF — making it a one-export-away upgrade for any cluster change review workflow.

You apply a change to a production Deployment. Before you do, you run
kubectl diff -f updated.yaml to check what's changing. What you get back is a wall of + and - lines — same as git diff, but on serialized YAML. Two list entries swapped? The diff shows thirty lines of churn. A key was renamed and the value stayed the same? Good luck spotting it.diffyml takes a different approach: it parses both YAML files as trees, matches nodes by key path, and reports changes by what moved rather than where lines fell. 1 The output is a flat list of semantic changes — spec.replicas: 2 → 3, spec.template.spec.containers.web-api.image: 1.4.2 → 2.0.0 — not a line-by-line text patch. For Kubernetes manifests specifically, it identifies resources by apiVersion + kind + metadata.name and can detect renames when two resources share more than 60% of their content. 1The tool is built by Sergei Zhekpisov (Katanox, London), written in Go, licensed MIT, and sitting at 51 stars as of today — discovered via Terminal Trove on May 26. 2 It has one external dependency (
gopkg.in/yaml.v3) and uses the Go standard library for everything else. 3正在加载内容卡片…
Install
Seven paths to the same binary (v1.6.2, released June 3, 2026): 1
Homebrew (macOS/Linux):
brew install szhekpisov/diffyml/diffymlGo toolchain:
go install github.com/szhekpisov/diffyml@latestCurl installer (Linux):
curl -sSfL https://raw.githubusercontent.com/szhekpisov/diffyml/main/install.sh | shDocker:
docker run --rm -v $(pwd):/work ghcr.io/szhekpisov/diffyml:latest old.yaml new.yamlOr build from source with
go build. All paths produce the same single static binary.A real scenario: reviewing a Kubernetes rollout before kubectl apply
Your team is about to roll a config change across a multi-service cluster. You have the updated manifests but want to confirm exactly what will change — not just whether YAML is syntactically valid.
First, point
diffyml at the two files directly:diffyml current-deployment.yaml updated-deployment.yamlThe output groups changes by YAML key path and resource identity. You'll see something like:
spec.replicas (apps/v1/Deployment/production/web-api)
± value change
- 2
+ 3
spec.template.spec.containers.web-api.image (apps/v1/Deployment/production/web-api)
± value change
- registry.example.com/web-api:1.4.2
+ registry.example.com/web-api:2.0.0
spec.template.spec.containers.web-api.env (apps/v1/Deployment/production/web-api)
+ one list entry added:
- name: ENABLE_METRICS
value: trueNo surrounding noise. No reordered list items flagged as changes.
For the review step before you actually apply, wire
diffyml directly into kubectl as an external diff driver:export KUBECTL_EXTERNAL_DIFF="diffyml --omit-header --set-exit-code"
kubectl diff -f updated-deployment.yamlFrom this point on,
kubectl diff uses diffyml's output format instead of the default unified diff. The --set-exit-code flag makes it exit non-zero when differences are found, so it plays cleanly with CI pipelines that gate on kubectl diff.
kubectl diff with KUBECTL_EXTERNAL_DIFF="diffyml --omit-header --set-exit-code"1The tool also works on directories (
diffyml ./old-configs/ ./new-configs/) and on remote URLs, so comparing a local override against a fetched upstream chart is a one-liner.What's under the hood
One external dependency. The entire tool is
gopkg.in/yaml.v3 plus Go's standard library — no SDK sprawl, easy to audit. 3 The author's framing in the README is accurate: "One dependency, zero surprises." 1Seven output formats.
detailed, compact, brief, json, and three CI-native formats: github (GitHub Actions annotations), gitlab, and gitea. Pass --format github and the diff lands in the Annotations panel of your Actions run, not buried in logs. 1API version migration support. The
--ignore-api-version flag lets you diff across extensions/v1beta1 → apps/v1 migrations without false positives on the apiVersion field itself. 1Supply chain. Every release is Cosign-signed, ships SLSA Level 3 provenance, and includes an SPDX SBOM. 1 That's more provenance than most tools twice its age.
The AI Summary feature (
--summary, requires ANTHROPIC_API_KEY) is fully optional. If the API call fails, the tool prints a warning to stderr and returns the normal diff output — exit code unaffected. 4The repository was created on February 23, 2026 and has accumulated 194 commits across 3.5 months of active development — an average of roughly 1.8 commits per day. 1
Caveats
- No community validation yet. Zero Hacker News threads, zero Reddit posts, zero Lobsters discussion. 2 Terminal Trove and daily.dev have listed it, but no engineer has written up a real-world experience. The 3.5-month timeline makes that normal rather than suspicious, but you'd be an early adopter with no forum trail to follow if something misbehaves.
- Performance claims are author-sourced. The README states diffyml is 1.5–1.9× faster than
dyffon files between 5K and 50K lines. 1 The methodology document (PERFORMANCE.md) was not accessible during research, so that number can't be independently verified at this time. - Single maintainer. Sergei Zhekpisov is the only contributor. Active pace, clean code, solid supply chain hygiene — but bus factor is 1.
dyffis the obvious comparison.dyff(humio/dyff) is the incumbent Go-based YAML diff tool with a larger community. If you're already using it and it's working,diffymloffers Kubernetes-aware resource matching and CI output formats as concrete reasons to switch — not just a different implementation of the same idea. If you're starting fresh,diffyml's install story is marginally simpler.
Install:
brew install szhekpisov/diffyml/diffyml or go install github.com/szhekpisov/diffyml@latest
围绕这条内容继续补充观点或上下文。