Ever stared at a massive JSON blob, knowing the data you need is in there somewhere, but dreading the trial-and-error dance to find the right jq query? Here’s a simple workflow using jless to visually find your data and instantly get the correct path for your jq queries.

Take this JSON object I was staring at this week:

{"v3": {"ext": "v0", "tx_changes_before": [{"state": {"last_modified_ledger_seq": 576947, "data": {"account":
{"account_id": "GAHYNUKBDZTUYLYMKQO3NMDSOI5S3AGUV63TGSTCQPCFNDYR2SD7UXMR", "balance": 199640926774, "seq_num":
849535941214249, "num_sub_entries": 0, "inflation_dest": null, "flags":
0, "home_domain": "", "thresholds": "01000000", "signers": [], "ext": {"v1": {"liabilities": {"buying": 0, "selling":
0}, "ext": {"v2": {"num_sponsored": 0, "num_sponsoring": 0, "signer_sponsoring_i_ds": [], "ext": {"v3":
{"ext": "v0", "seq_ledger": 576941, "seq_time": 1745292857}}}}}}}}, "ext": "v0"}}, {"updated":
{"last_modified_ledger_seq": 576947, "data": {"account":
{"account_id": "GAHYNUKBDZTUYLYMKQO3NMDSOI5S3AGUV63TGSTCQPCFNDYR2SD7UXMR", "balance": 199640926774, "seq_num":
849535941214250, "num_sub_entries": 0, "inflation_dest": null, "flags":
0, "home_domain": "", "thresholds": "01000000", "signers": [], "ext": {"v1": {"liabilities": {"buying": 0, "selling":
0}, "ext": {"v2": {"num_sponsored": 0, "num_sponsoring": 0, "signer_sponsoring_i_ds": [], "ext": {"v3":
{"ext": "v0", "seq_ledger": 576947, "seq_time": 1745292887}}}}}}}}, "ext": "v0"}}], "operations": [{"changes": [
{"created": {"last_modified_ledger_seq": 576947, "data": {"ttl":
{"key_hash": "31601ed0f9f61b2bd50d8c46a02e62094d2ae134439352b8eb5e01e3cd556768", "live_until_ledger_seq":
2650546}}, "ext": "v0"}}, {"created": {"last_modified_ledger_seq": 576947, "data": {"contract_code": {"ext": {"v1":
{"ext": "v0", "cost_inputs": {"ext": "v0", "n_instructions": 64, "n_functions": 4, "n_globals": 3, "n_table_entries":
0, "n_types": 4, "n_data_segments": 0, "n_elem_segments": 0, "n_imports": 4, "n_exports": 5, "n_data_segment_bytes":
0}}}, "hash": "ee240a935ea517d01ece74491d71f9ac6c4263aa611bc5be027b7e301fed85c4", "code": "0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aab0104960103017f017e017f41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041026a22022000490d01428ebad0af86d4392002ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d6574617630000000000000001600000000006f0e636f6e74726163746d65746176300000000000000005727376657200000000000006312e38312e3000000000000000000008727373646b7665720000002f32322e302e37233231313536396161343963386438393638373764666361316632656234666539303731313231633800"}},
"ext": "v0"}}]}], "tx_changes_after": [{"state": {"last_modified_ledger_seq": 576947, "data": {"account":
{"account_id": "GAHYNUKBDZTUYLYMKQO3NMDSOI5S3AGUV63TGSTCQPCFNDYR2SD7UXMR", "balance": 199640926774, "seq_num":
849535941214250, "num_sub_entries": 0, "inflation_dest": null, "flags":
0, "home_domain": "", "thresholds": "01000000", "signers": [], "ext": {"v1": {"liabilities": {"buying": 0, "selling":
0}, "ext": {"v2": {"num_sponsored": 0, "num_sponsoring": 0, "signer_sponsoring_i_ds": [], "ext": {"v3":
{"ext": "v0", "seq_ledger": 576947, "seq_time": 1745292887}}}}}}}}, "ext": "v0"}}, {"updated":
{"last_modified_ledger_seq": 576947, "data": {"account":
{"account_id": "GAHYNUKBDZTUYLYMKQO3NMDSOI5S3AGUV63TGSTCQPCFNDYR2SD7UXMR", "balance": 199642052390, "seq_num":
849535941214250, "num_sub_entries": 0, "inflation_dest": null, "flags":
0, "home_domain": "", "thresholds": "01000000", "signers": [], "ext": {"v1": {"liabilities": {"buying": 0, "selling":
0}, "ext": {"v2": {"num_sponsored": 0, "num_sponsoring": 0, "signer_sponsoring_i_ds": [], "ext": {"v3":
{"ext": "v0", "seq_ledger": 576947, "seq_time": 1745292887}}}}}}}}, "ext": "v0"}}], "soroban_meta": {"ext": {"v1":
{"ext": "v0", "total_non_refundable_resource_fee_charged": 46584, "total_refundable_resource_fee_charged":
7204795, "rent_fee_charged": 7204404}}, "events": [], "return_value":
{"bytes": "ee240a935ea517d01ece74491d71f9ac6c4263aa611bc5be027b7e301fed85c4"}, "diagnostic_events": [
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "read_entry"}], "data": {"u64": 1}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "write_entry"}], "data": {"u64": 1}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "ledger_read_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "ledger_write_byte"}], "data": {"u64": 688}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "read_key_byte"}], "data": {"u64": 36}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "write_key_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "read_data_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "write_data_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "read_code_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "write_code_byte"}], "data": {"u64": 688}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "emit_event"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "emit_event_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "cpu_insn"}], "data": {"u64": 1528767}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "mem_byte"}], "data": {"u64": 1446547}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "invoke_time_nsecs"}], "data": {"u64": 313924}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "max_rw_key_byte"}], "data": {"u64": 36}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "max_rw_data_byte"}], "data": {"u64": 0}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "max_rw_code_byte"}], "data": {"u64": 688}}}}},
{"in_successful_contract_call": false, "event": {"ext": "v0", "contract_id": null, "type_": "diagnostic", "body":
{"v0": {"topics": [{"symbol": "core_metrics"}, {"symbol": "max_emit_event_byte"}], "data": {"u64": 0}}}}}]}}}

The JSON contains information about a contract invocation and a transaction executed on the Stellar network. To extract the contract function’s return value, the jq query is:

.v3.soroban_meta.return_value

It looks simple, but isn’t simple to find when staring at a large JSON object.

jless: An Interactive JSON Explorer

jless is an interactive command-line JSON viewer that makes navigating complex JSON structures intuitive. Think of it as less but purpose-built for JSON. Unlike plain less or cat, jless understands JSON structure, allowing for easy exploration with features like:

  • Expanding/collapsing nodes with space.
  • Search functionality with /.
  • jq query copying 👈 the key feature we’ll use.

The Workflow

Let’s walk through a practical example. Save the above JSON as data.json then follow the steps below.

Step 1: View the JSON in jless

jless data.json

Step 2: Find the field you want

Use the search feature / to find the return_value field.

Press /, type return_value, then press Enter.

Step 3: Copy the JSON path with yq

With the return_value field highlighted, press y followed by q.

This will yank the query path into the system clipboard. jless will confirm “Copied query path to clipboard” in its status line.

The copied path will be:

.v3.soroban_meta.return_value

Step 4: Paste into your jq query

Now construct jq command by pasting the copied path:

jq '.v3.soroban_meta.return_value' data.json

Output:

{
  "bytes": "ee240a935ea517d01ece74491d71f9ac6c4263aa611bc5be027b7e301fed85c4"
}

Celebrate

No guesswork, no trial and error. The query path given to you when you point at the field.

Give this workflow a try on your next JSON exploration.

Happy JSON wrangling! 🎉