Answer: jq is a command-line JSON processor, and a filter like .order.items | map(.qty * .price) | add sums a cart: on the sample below that's 728, plus $18.50 shipping = 746.50. This playground runs jq 1.8.2 — compiled to WebAssembly from the official jqlang/jq source — so filters, flags, and error messages match the CLI exactly. Output updates as you type, and your JSON never leaves the page.

JSON In, Filter, Result Out loading engine…

Advertisement

jq Filter Cheat Sheet

FilterWhat it doesOn the sample order
.Identity — the input unchangedthe whole order object
.order.customer.nameWalk a path"Dana Reyes"
.order.items | lengthCount array elements3
.order.items[]Stream every element3 separate item objects
.order.items[] | .qty * .priceArithmetic per element129, 549, 50
map(.qty * .price) | addCollect then sum728
select(.price > 100)Keep matching valueskeyboard + desk
sort_by(-(.qty * .price)) | .[0]Order and indexthe standing desk
keysArray of an object's keys["order"]
to_entriesObject → key/value array5 entries: id, customer, items…
[.order.items[].price] | min, maxStatistics on collected values25 and 549
"\(.sku): \(.qty) x $\(.price)"String interpolationKB-01: 1 x $129
.missing // "none"Alternative for null/false"none"

Every value in the right column was produced by this page's engine on the default sample — click the chips above to reproduce each one.

How the jq Playground Works

jq, written by Stephen Dolan and maintained today as jqlang/jq (MIT license), is the JSON processor: a tiny language for slicing, filtering, and reshaping JSON that has become the connective tissue of shell pipelines everywhere. The official playground at jqplay.org inspired this page's layout — JSON on the left, filter in the middle, live output — but here the engine runs in your tab: jq 1.8.2 compiled to WebAssembly through the MIT-licensed jq-wasm build, roughly 900 KB fetched once from the jsDelivr CDN. After that, every keystroke re-runs your filter locally.

Filters are pipelines

The mental model is a Unix pipe. .order.items selects a value; | length feeds that value to the length function; [] explodes an array into a stream where each element runs through whatever follows. Because filters are values too, map(f) is just [.[] | f] with a name. That composability is why one-liners like .items | map(select(.qty > 0)) | map(.qty * .price) | add read left to right as a sentence.

How to use it

Paste any JSON on the left, type a filter, and the output pane updates as you type. The checkboxes map to the CLI flags you'd actually use: -r for unquoted strings, -c for one-line compact output, -S for sorted keys. Errors appear verbatim from jq's own stderr with the exit code, which is precisely what you'd see in a terminal — useful when you're debugging a filter for a script. The chips load worked filters against the sample order.

A worked example

The sample document is one order: three line items (keyboard $129, standing desk $549, two desk mats at $25) and $18.50 express shipping. Start simple: .order.items | length is 3. Multiply per line: .order.items[] | .qty * .price streams 129, 549, 50. Sum with map(.qty * .price) | add to get the subtotal 728, then bind it and add shipping — .order as $o | ($o.items | map(.qty * .price) | add) + $o.shipping.cost — for the 746.50 total. Interpolation turns the items into report lines: .order.items[] | "\(.sku): \(.qty) x $\(.price)" prints KB-01: 1 x $129 and friends under the -r flag. Average unit price divides 728 by 4 total units: 182 exactly.

Frequently Asked Questions

What is jq used for?

jq slices, filters, and reshapes JSON on the command line. You feed it a document and a filter — like .items[] | select(.price > 100) | .name — and it streams out the matching values. It's the standard tool for reading API responses, transforming configs, and massaging logs: anything where you'd otherwise write a 20-line Python script gets done in one jq expression.

Is this the real jq or a reimplementation?

Real jq. This page loads jq 1.8.2 — the current release from the jqlang/jq project — compiled to WebAssembly via the MIT-licensed jq-wasm build, and executes it locally. Filter semantics, error messages, and flags like -r and -c behave exactly like the jq binary; the version check in the header reports the engine's own version string.

What does the pipe operator do in jq?

The pipe chains filters the way Unix pipes chain commands: .items | length first selects the items array, then feeds it to length. Each stage's output becomes the next stage's input. Combined with map() and select(), the pipe is how you express 'take this, keep those, transform each' in one readable line.

How do I output plain strings instead of JSON quotes?

Use the raw output flag. jq's -r prints string results without quotes and without escapes, so "[email protected]" comes out as [email protected]. This playground exposes -r, -c (compact), and -S (sort object keys) as checkboxes that map straight onto the CLI flags.

Why did my filter return null?

Almost always an optional-access question: .foo on an object without foo gives null rather than an error, and null flows silently through the rest of the pipeline. If you queried an array element that doesn't exist, you also get null. Track it by simplifying the filter stage by stage — run .first, then add the pipe — until the null appears. Use .foo? or try/catch when missing keys are expected.

Can I use string interpolation in jq?

Yes, and it's the neat way to build lines for reports. Inside a string, \(expression) interpolates: "\(.sku): \(.qty) x $\(.price)" turns each item object into one readable line. Combined with the -r flag it produces exactly the kind of output you'd pipe into a file or spreadsheet.

Advertisement