dyff: Structural Diff for YAML and JSON
dyff compares two YAML or JSON files structurally and reports changes by document path, which is far more readable than a line diff of reformatted YAML.
YAML line diffs are notoriously noisy because of indentation and key order. dyff parses the documents and shows only the real changes, which is why it is popular for Kubernetes and Helm output.
What it does
dyff between parses two YAML/JSON inputs and prints a structural diff: added, removed, and changed values with their dotted or slash paths. It ignores key order and formatting differences. Its exit code is nonzero when the documents differ, so it can gate a pipeline.
Common usage
dyff between old.yaml new.yaml
# quiet header, good for logs
dyff between --omit-header old.yaml new.yaml
# compare rendered Helm output to what is committed
helm template . | dyff between committed.yaml -Options
| Flag / subcommand | What it does |
|---|---|
| between <a> <b> | Diff two documents |
| --omit-header | Suppress the summary header |
| --set-exit-code | Exit nonzero when there are differences |
| --ignore-order-changes | Do not report list reordering as a change |
| -i / --ignore | Ignore differences under a given path |
| --output <fmt> | human (default), brief, or github |
In CI
Render manifests and compare them to the committed copy: helm template . | dyff between --set-exit-code committed.yaml -. Pass --set-exit-code so a real structural change fails the job while indentation or key-order churn does not. This catches drift in generated Kubernetes YAML without the false alarms of a text diff.
Common errors in CI
A green build that should be red often means --set-exit-code was omitted; by default dyff prints the diff but may exit 0. "failed to load input" means the YAML is invalid or the stream had multiple documents dyff could not split; check the --- separators. "dyff: command not found" means the Go binary is not installed.