json-subset

command module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT Imports: 7 Imported by: 0

README

json-subset

A command-line tool for checking if one JSON is a subset of another. Arrays are compared as sets, ignoring element order.

Why json-subset?

You often need to verify that an HTTP API response contains expected fields:

# Does this response contain our required fields?
curl -s https://api.example.com/config > response.json
Why Not jq?

jq's contains function can check subsets:

$ jq -s '.[0] as $a | .[1] | contains($a)' required.json response.json

However, it only returns true or false. When validation fails, you don't know what is missing:

false

You could write complex jq expressions to show differences, but they become hard to maintain:

$ jq -s '
  .[0] as $sub | .[1] as $sup |
  [
    $sub | paths(scalars) | . as $p |
    {
      path: ($p | map(tostring) | join(".")),
      subset_value: ($sub | getpath($p)),
      superset_value: ($sup | getpath($p))
    } |
    select(.subset_value != .superset_value)
  ]
' required.json response.json

This is jq wizardry that's difficult to understand, modify, or hand off to teammates.

Why Not jd?

jd is excellent for equality checks and showing diffs:

$ jd -set a.json b.json

But jd doesn't have a subset mode. It tells you everything that's different, not whether one JSON is contained within another.

json-subsets Role

json-subset does one thing: subset checking with clear difference output.

$ json-subset required.json response.json
FAIL: First JSON is not a subset of second JSON.

 {
   "user": {
-    "email": "alice@example.com",
     "name": "alice"
   }
 }

When validation fails, you immediately see what's wrong. The - marker shows which fields are missing or have mismatched values.

Tool Responsibilities
Task Tool
JSON equality check jd
JSON transformation/filtering jq
Subset validation with diff json-subset

Usage

$ json-subset <subset.json> <superset.json>
Examples

Check if required fields exist in API response:

$ json-subset required.json response.json

With curl and process substitution:

$ json-subset expected.json <(curl -s https://api.example.com/config)

With jq preprocessing to remove dynamic fields:

$ json-subset expected.json <(curl -s https://api.example.com/config | jq 'del(.timestamp)')
Exit Codes
  • 0: Success (first JSON is a subset of second)
  • 1: Failure (first JSON is not a subset of second)
  • 2: Error (invalid input, file not found, etc.)

Behavior

Object Comparison

An object A is a subset of object B if:

  • Every key in A exists in B
  • For each key, the value in A is a subset of the value in B
# subset.json
{"name": "alice"}

# superset.json
{"name": "alice", "age": 30}

# Result: OK (subset)
Array Comparison (Set Mode)

Arrays are compared as sets. Element order is ignored.

# subset.json
[2, 1]

# superset.json
[1, 2, 3]

# Result: OK (subset, order ignored)
Nested Structures

Subset checking works recursively for nested objects and arrays.

# subset.json
{"user": {"name": "alice"}}

# superset.json
{"user": {"name": "alice", "age": 30}, "metadata": {}}

# Result: OK (subset)

Difference Output

When the subset check fails, json-subset displays the subset JSON with diff markers. Lines prefixed with - indicate missing keys or mismatched values:

FAIL: First JSON is not a subset of second JSON.

 {
-  "license": "MIT",
   "name": "myapp",
   "version": "1.0.0"
 }

For nested structures:

FAIL: First JSON is not a subset of second JSON.

 {
   "user": {
-    "email": "alice@example.com",
     "name": "alice"
   }
 }

For arrays:

FAIL: First JSON is not a subset of second JSON.

 {
   "tags": [
     "production",
     "stable",
-    "admin"
   ]
 }

Examples

The examples/ directory contains sample JSON files for testing:

Success case: required fields exist in response:

json-subset examples/required.json examples/response.json

Failure case: required field missing:

$ json-subset examples/required_with_missing.json examples/response.json

Array subset (order ignored):

$ json-subset examples/required_tags.json examples/actual_tags.json

Nested object subset:

$ json-subset examples/required_nested.json examples/response_nested.json

Complex API response with multiple missing fields:

$ json-subset examples/required_api_response.json examples/actual_api_response.json
FAIL: First JSON is not a subset of second JSON.

 {
   "data": {
-    "permissions": [
-      "read",
-      "write"
-    ],
     "user": {
       "id": 123,
       "profile": {
-        "email": "alice@example.com",
         "name": "alice"
       }
     }
   },
   "status": "success"
 }

License

This project is licensed under the MIT License.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL