A powerful cross-format diff tool that compares JSON, YAML, and other structured data files with an intuitive unified diff output. By default, diffnest shows only the differences between files, making it easy to spot changes in large configuration files.
- Cross-format comparison: Compare files in different formats (JSON vs YAML)
- Multiple document support: Handle multiple documents in a single file with optimal pairing using the Hungarian algorithm
- Smart array comparison: Compare arrays by index or by value matching
- Multiple output formats: Unified diff (default) or JSON Patch (RFC 6902)
- Detailed multiline string diffs: Line-by-line comparison for multiline strings
- Context control: Adjustable context lines around changes for better readability
- Flexible options: Ignore zero values, show only differences, and more
- Standard input support: Compare files from stdin using
-
go install github.com/sters/diffnest@latestDownload pre-built binaries from Releases.
# Compare two JSON files
diffnest file1.json file2.json
# Compare JSON and YAML files
diffnest config.json config.yaml
# Compare from stdin
cat file1.json | diffnest - file2.json-show-all Show all fields including unchanged ones (default: show only differences)
-ignore-zero-values Treat zero values (0, false, "", [], {}) as null
-ignore-empty Ignore empty fields
-ignore-key-case Ignore case differences in object keys
-ignore-value-case Ignore case differences in string values
-array-strategy Array comparison strategy: 'index' or 'value' (default: value)
-format Output format: 'unified' or 'json-patch' (default: unified)
-format1 Format for first file: 'json', 'yaml', or auto-detect
-format2 Format for second file: 'json', 'yaml', or auto-detect
-C Number of context lines to show (incompatible with -show-all, default: 3)
-v Verbose output
-h Show help
# By default, only differences are shown
diffnest actual.json expected.jsondiffnest -show-all actual.json expected.jsondiffnest -array-strategy index list1.yaml list2.yamldiffnest -format json-patch old.json new.jsondiffnest -ignore-zero-values sparse1.json sparse2.json# Show only changed lines (no context)
diffnest -C 0 file1.json file2.json
# Show more context around changes
diffnest -C 5 file1.json file2.json# Ignore case differences in object keys
diffnest --ignore-key-case config1.json config2.json
# Ignore case differences in string values
diffnest --ignore-value-case data1.json data2.json
# Ignore case in both keys and values
diffnest --ignore-key-case --ignore-value-case file1.json file2.json- name: oldValue
+ name: newValue
unchanged: sameValue
+ added: newField
- removed: deletedField[
{"op": "replace", "path": "/name", "value": "newValue"},
{"op": "add", "path": "/added", "value": "newField"},
{"op": "remove", "path": "/removed"}
]diffnest can seamlessly compare files in different formats:
# Compare JSON config with YAML config
diffnest app.json app.yamlYAML files with multiple documents (separated by ---) are fully supported:
---
doc1: value1
---
doc2: value2When comparing files with multiple documents, diffnest uses the Hungarian algorithm to find the optimal pairing between documents. This ensures that similar documents are matched together, minimizing the total differences reported.
For Kubernetes-like resources, diffnest applies additional matching heuristics based on:
kind(highest priority - different kinds are strongly discouraged from matching)apiVersion
This means when comparing two Kubernetes manifest files, resources of the same kind will be matched based on content similarity. If a resource is renamed (e.g., metadata.name changed), it will be shown as "modified" rather than "deleted + added", making it easier to see what actually changed.
Choose between two array comparison strategies:
value(default): Finds the best matching between array elementsindex: Compares arrays by position
# Smart matching (reordered elements are considered equal)
diffnest -array-strategy value items1.json items2.json
# Strict ordering (position matters)
diffnest -array-strategy index items1.json items2.jsonMultiline strings are compared line-by-line for better readability:
config:
- line 1: old text
+ line 1: new text
line 2: unchanged
+ line 3: added lineThe -C option allows you to control how many unchanged lines are shown around changes, similar to traditional diff tools. This option is only available when showing differences (default behavior) and cannot be used with -show-all:
# Show minimal context (only changed lines)
diffnest -C 0 file1.json file2.json
# Invalid: cannot combine -C with -show-all
# diffnest -show-all -C 2 file1.json file2.json # Error!Example output with -C 0:
- field3: old
+ field3: newExample output with -C 2:
field1: value1
field2: value2
- field3: old
+ field3: new
field4: value4
field5: value5Example output with -show-all:
field1: value1
field2: value2
- field3: old
+ field3: new
field4: value4
field5: value5
field6: value6
field7: value7
... (all fields shown)For large files with scattered changes, context control helps focus on what matters:
field2: value2
- field3: old
+ field3: new
field4: value4
...
field98: value98
- field99: old
+ field99: new
field100: value100Important: The -C option is incompatible with -show-all. When using -show-all, all fields are displayed regardless of context settings.
diffnest provides granular control over case sensitivity:
# Without --ignore-key-case (default)
diffnest file1.json file2.json- Name: John
+ name: John# With --ignore-key-case
diffnest --ignore-key-case file1.json file2.json(no differences - keys "Name" and "name" are considered the same)# Without --ignore-value-case (default)
diffnest file1.json file2.json- status: ACTIVE
+ status: active# With --ignore-value-case
diffnest --ignore-value-case file1.json file2.json(no differences - values "ACTIVE" and "active" are considered the same)Some options are incompatible and cannot be used together:
-show-alland-C: Context lines are only meaningful when showing differences. When using-show-all, all fields are displayed.
0: No differences found1: Differences found or error occurred
diffnest can also be used as a Go library:
import "github.com/sters/diffnest/diffnest"
// Compare two data structures
opts := diffnest.DiffOptions{
ArrayDiffStrategy: diffnest.ArrayStrategyValue,
}
results := diffnest.Compare(data1, data2, opts)
// Format the results
formatter := &diffnest.UnifiedFormatter{
ShowOnlyDiff: true,
ContextLines: 3, // Number of context lines
}
formatter.Format(os.Stdout, results)