jq Playground
Run jq 1.7.1 filters in your browser with -r, -s, -n, --arg and JSON Lines. Output, stderr and exit codes match the jq CLI; error hints show the bad spot.
- Runs in your browser
- Your data never leaves your browser
- Free · No Sign-Up
Scan with WeChat to share this tool
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.
Example: open pull requests by one author
A GitHub REST API list response (shortened) in Input, -r on, and a variable who = octocat:
[{"number":42,"title":"Fix login redirect","draft":false,"user":{"login":"octocat"}},
{"number":43,"title":"WIP: new parser","draft":true,"user":{"login":"hubot"}},
{"number":44,"title":"Bump jq to 1.7.1","draft":false,"user":{"login":"octocat"}}]
.[] | select(.draft | not) | select(.user.login == $who) | "#\(.number)\t\(.title)"
Output (2 lines, tab-separated):
#42 Fix login redirect
#44 Bump jq to 1.7.1
The Command line box reads jq -r --arg who octocat '.[] | select(.draft | not) | …' input.json. If you call the API with GitHub CLI instead, note that gh api … --jq does not run jq: it uses gojq, a Go reimplementation, and prints top-level strings raw as if -r were on (go-gh pkg/jq). The gojq README lists the differences: it does not keep object key order, has no -S, -a or --seq, and keeps integer precision in arithmetic where jq does not.
Example: summarise JSON Lines logs
Access logs often have one JSON object per line. With -s (slurp) and -c:
{"ts":"2026-10-01T09:00:01Z","path":"/api/orders","status":200,"ms":42}
{"ts":"2026-10-01T09:00:02Z","path":"/api/orders","status":500,"ms":1203}
{"ts":"2026-10-01T09:00:02Z","path":"/health","status":200,"ms":3}
{"ts":"2026-10-01T09:00:03Z","path":"/api/orders","status":200,"ms":57}
group_by(.path) | map({path: .[0].path, requests: length,
errors: map(select(.status >= 500)) | length, avg_ms: (map(.ms) | add / length)})
[{"path":"/api/orders","requests":3,"errors":1,"avg_ms":434},{"path":"/health","requests":1,"errors":0,"avg_ms":3}]
-s holds every line in memory. For large files, -n with reduce inputs as $r (…) reads one value at a time; the Options: —arg, -s, -n, -R group in Examples has both forms.
When jq stops with an error
jq prints the values it produced before the error, then the error on stderr, and exits with code 5. The page keeps both:
.items[] | .tags[] on {"items":[{"id":1,"tags":["a"]},{"id":2,"tags":null},{"id":3,"tags":["b","c"]}]} outputs "a", then jq: error (at input.json:1): Cannot iterate over null (null) and exit code 5. The hint below suggests .tags[]? or (.tags // [])[]. For a JSON syntax error, Show in input selects the token jq stopped at; jq reports the position in bytes, and the page converts it so that {"日本":1 x} selects the x. For a filter error, Show in filter selects the reported line.
The page also catches mistakes jq only reports as unexpected INVALID_CHARACTER: curly quotes from a word processor, fullwidth | or . from an input method, and a filter still wrapped in shell quotes.
Same result as your terminal
Each run is jq FLAGS FILTER input.json, where input.json holds the input plus a final newline. Our test suite runs 71 cases (options, variables, JSON Lines, syntax and runtime errors, halt_error, -e, --seq, --stream) through this page’s engine and through jq 1.7.1, and compares stdout, stderr and the exit code byte for byte. It also runs the 241 examples of the jq 1.7.1 manual; all match except the two that read $PAGER from the environment.
Which jq do you have? Run jq --version. Ubuntu 24.04 (jq 1.7.1-3ubuntu0.24.04), Debian 13 (1.7.1-6) and macOS 27 (/usr/bin/jq prints jq-1.7.1-apple) have 1.7.1. Homebrew has 1.8.2. jq 1.8.0 (NEWS) added trim, ltrim, rtrim, trimstr, toboolean, skip, add/1 and @urid, made ltrimstr error on non-strings and limit error on a negative count, and changed how -1 as $x | … binds. Large integers are kept as written, but arithmetic uses doubles in 1.7.1:
.order_id, .order_id + 0 on {"order_id": 9007199254740993} prints 9007199254740993 and then 9007199254740992.
How it compares (tested 2026-10-02)
We ran the same inputs on three other jq pages in Chromium:
- play.jqlang.org (the jq project’s playground; jqplay.org now redirects there) runs jq 1.8 in the browser:
trimworks and no request carried our input. It shows output and error together, as here, and stoppedrepeat(1)with “Operation timed out” after about 30 seconds. Use it when you run jq 1.8. - jqkungfu.com runs jq.wasm locally. For
.[] | .aon[{"a":1},2]it showed1without the error;9007199254740993came back as9007199254740992; after a JSON syntax error the previous output stayed on screen. - jsonwiz.com/jq-online loads
jq-wasm@0.3.1from esm.sh, which answered 404, so every run showed “Failed to fetch dynamically imported module”.
Limits
- No files besides the input:
--slurpfile,--rawfile,-f,-L,importandincludeare not available;--args/--jsonargsare left out. $ENVandenvshow the WebAssembly runtime’s fixed environment (HOME=/home/web_user), not yours.nowand the local-time functions use your browser’s clock.- Inputs over 2 MB run only when you press Run; files over 2 MB are not shown in the editor. Output over 1 MB is cut in the panel (Copy and Download are complete).
- A filter is stopped after 10 seconds plus 1 second per MB of input. A run that exhausts memory or recurses too deep restarts the engine.
- Colour (
-C) is ignored; output is not colourised.
Related tools: JSONPath Tester for path queries, JSON Formatter to pretty-print, JSONL Converter between JSON arrays and JSON Lines, JSON Diff to compare two outputs.
FAQ
Is this the real jq or a JavaScript copy?
It is jq 1.7.1 itself: the official C source compiled to WebAssembly by jq-web 0.6.2. The page runs it the way `jq FLAGS FILTER input.json` runs, and our test suite compares 71 filters byte for byte (output, error text, exit code) with the jq 1.7.1 command line, plus the 239 examples of the jq 1.7.1 manual that do not read environment variables.
Why jq 1.7.1 and not 1.8?
1.7.1 is the jq that Ubuntu 24.04, Debian 13 and macOS (/usr/bin/jq) ship, so a filter tested here behaves the same on those machines. jq 1.8 adds trim, ltrim, rtrim, trimstr, toboolean, skip, add/1 and @urid and changes a few behaviours; when a filter uses a 1.8 function, the page says so.
Is my JSON uploaded?
No. jq runs in a Web Worker in your tab. The only network requests are the jq engine files the first time you use the tool (jq.wasm, about 1 MB compressed). The share link carries the filter, the options and the variable names, never the input or the variable values.
Does the page remember what I typed?
Yes, in this browser only. The filter, the options, the variables (names and values) and an input of up to 40 KB that you type or paste are saved in this browser's local storage and come back when you open the page again. Opened files and larger inputs are not saved. Clear removes the saved input; the filter stays until you change it.
How big can the input be?
Files up to 200 MB. Inputs over 2 MB do not run on every keystroke; press Run. The output panel renders the first 1 MB and Copy / Download give the whole output. A filter that runs longer than 10 seconds (plus 1 second per MB of input) is stopped.
My filter works here but not in my shell. Why?
Usually quoting. Copy the command from the Command line box: it puts the filter in single quotes and escapes any single quote inside it, which is what bash and zsh need. PowerShell and cmd.exe quote differently. Also check `jq --version`: on jq 1.8 a few results differ.