jq Playground Online

Test jq filters on your JSON instantly. This online jq playground runs the real jq 1.8.2 compiled to WebAssembly, right in your browser: no sign-up, and your data never leaves your device.

jq options
Output Loading jq (WebAssembly)…

Output updates as you type. New to jq? Start from the jq examples below or read the jq manual.

Use jq every day? Run it in VS Code

jq Playground for VS Code turns jq into a notebook: keep filters in .jqpg files, run them against workspace files, URLs and shell commands, with autocomplete and Copilot-powered explain and fix. 33k+ installs, free and open source.

jq examples and cheat sheet

Common jq filters with sample input and the exact output of jq 1.8.2. Press Run to load any example into the playground and edit it.

Basics

Access fields, arrays and nested values.

Pretty-print JSON

Run

The identity filter . returns the input unchanged, formatted and indented.

jq '.'
Input
{"name":"Alice","tags":["admin","dev"],"active":true}
Output
{
  "name": "Alice",
  "tags": [
    "admin",
    "dev"
  ],
  "active": true
}

Get a field from an object

Run

Use .key to read a single field. Missing keys return null instead of failing.

jq '.name'
Input
{"name": "Alice", "email": "alice@example.com"}
Output
"Alice"

Read a nested field

Run

Chain keys to walk into nested objects.

jq '.user.address.city'
Input
{"user": {"address": {"city": "Lugano", "zip": "6900"}}}
Output
"Lugano"

Array index and slice

Run

.[0] is the first element, .[-1] the last, .[1:3] a slice.

jq '[.[0], .[-1], .[1:3]]'
Input
["a", "b", "c", "d"]
Output
["a","d",["b","c"]]

Iterate over an array

Run

.[] emits every element; pipe each one into the next filter.

jq '.users[].name'
Input
{"users": [{"name": "Alice"}, {"name": "Bob"}]}
Output
"Alice"
"Bob"

List keys and count items

Run

keys returns sorted object keys; length counts elements, keys or characters.

jq '{keys: keys, count: length}'
Input
{"b": 2, "a": 1, "c": 3}
Output
{"keys":["a","b","c"],"count":3}

Filter and select

Keep only the values you need.

Filter an array with select

Run

select(cond) keeps the values for which the condition is true.

jq 'map(select(.active) | .name)'
Input
[{"name": "Alice", "age": 34, "active": true, "dept": "eng"}, {"name": "Bob", "age": 27, "active": false, "dept": "ops"}, {"name": "Carol", "age": 41, "active": true, "dept": "eng"}]
Output
["Alice","Carol"]

Select objects by a numeric field

Run

Combine select with comparison operators.

jq '.[] | select(.age > 30) | .name'
Input
[{"name": "Alice", "age": 34, "active": true, "dept": "eng"}, {"name": "Bob", "age": 27, "active": false, "dept": "ops"}, {"name": "Carol", "age": 41, "active": true, "dept": "eng"}]
Output
"Alice"
"Carol"

Match strings with a regex

Run

test(regex) returns true when the string matches.

jq 'map(select(.email | test("@example\\.com$")))'
Input
[{"email": "alice@example.com"}, {"email": "bob@test.org"}]
Output
[{"email":"alice@example.com"}]

Check whether an array contains a value

Run

index(value) or any(...) find a value inside an array.

jq 'map(select(any(.tags[]; . == "jq")) | .name)'
Input
[{"name": "a", "tags": ["jq", "json"]}, {"name": "b", "tags": ["yaml"]}]
Output
["a"]

Check if a key exists

Run

has(key) tests for a key, even when its value is null.

jq 'map(has("email"))'
Input
[{"email": null}, {"name": "Bob"}]
Output
[true,false]

Get the first match only

Run

first(expr) stops after the first output.

jq 'first(.[] | select(.age > 30)) | .name'
Input
[{"name": "Alice", "age": 34, "active": true, "dept": "eng"}, {"name": "Bob", "age": 27, "active": false, "dept": "ops"}, {"name": "Carol", "age": 41, "active": true, "dept": "eng"}]
Output
"Alice"

Transform

Reshape objects and arrays.

Transform every element with map

Run

map(f) applies a filter to each array element.

jq 'map(.price * .qty)'
Input
[{"price": 3, "qty": 2}, {"price": 10, "qty": 1}]
Output
[6,10]

Build a new object

Run

Use {} to pick and rename fields.

jq 'map({user: .name, isAdult: (.age >= 18)})'
Input
[{"name": "Alice", "age": 34}, {"name": "Tim", "age": 12}]
Output
[{"user":"Alice","isAdult":true},{"user":"Tim","isAdult":false}]

Delete a key

Run

del(path) removes fields, e.g. secrets before sharing a payload.

jq 'del(.password, .token)'
Input
{"user": "alice", "password": "s3cret", "token": "abc"}
Output
{"user":"alice"}

Update values in place

Run

|= updates the value at a path and keeps the rest of the document.

jq '.items[].price |= . * 2'
Input
{"items": [{"id": 1, "price": 5}, {"id": 2, "price": 8}]}
Output
{"items":[{"id":1,"price":10},{"id":2,"price":16}]}

Rename all keys with with_entries

Run

with_entries lets you rewrite keys and values of an object.

jq 'with_entries(.key |= ascii_upcase)'
Input
{"host": "localhost", "port": 8080}
Output
{"HOST":"localhost","PORT":8080}

Provide a default value

Run

The alternative operator // replaces null or false with a fallback.

jq 'map(.nickname // "anonymous")'
Input
[{"nickname": "ally"}, {"name": "Bob"}]
Output
["ally","anonymous"]

Conditional values with if-then-else

Run

jq has full if ... then ... elif ... else ... end expressions.

jq 'map(if .score >= 60 then "pass" else "fail" end)'
Input
[{"score": 72}, {"score": 45}]
Output
["pass","fail"]

Merge objects

Run

* deep-merges two objects; add merges an array of objects.

jq '.defaults * .overrides'
Input
{"defaults": {"debug": false, "db": {"host": "localhost", "port": 5432}}, "overrides": {"db": {"host": "db.internal"}}}
Output
{"debug":false,"db":{"host":"db.internal","port":5432}}

Sort, group and aggregate

Summaries and reports from arrays of objects.

Sort an array of objects by a field

Run

sort_by(f) sorts ascending; add reverse for descending order.

jq 'sort_by(.age) | reverse | map(.name)'
Input
[{"name": "Alice", "age": 34, "active": true, "dept": "eng"}, {"name": "Bob", "age": 27, "active": false, "dept": "ops"}, {"name": "Carol", "age": 41, "active": true, "dept": "eng"}]
Output
["Carol","Alice","Bob"]

Group by a field and count

Run

group_by(f) groups equal values; build one summary object per group.

jq 'group_by(.dept) | map({dept: .[0].dept, count: length})'
Input
[{"name": "Alice", "age": 34, "active": true, "dept": "eng"}, {"name": "Bob", "age": 27, "active": false, "dept": "ops"}, {"name": "Carol", "age": 41, "active": true, "dept": "eng"}]
Output
[{"dept":"eng","count":2},{"dept":"ops","count":1}]

Sum values

Run

add sums numbers (and concatenates strings or arrays).

jq 'map(.amount) | add'
Input
[{"amount": 12.5}, {"amount": 7.5}, {"amount": 30}]
Output
50

Unique values

Run

unique sorts and removes duplicates; unique_by(f) dedupes by a key.

jq 'map(.tag) | unique'
Input
[{"tag": "b"}, {"tag": "a"}, {"tag": "b"}]
Output
["a","b"]

Find min and max by a field

Run

min_by(f) and max_by(f) return the whole matching object.

jq '{cheapest: min_by(.price).name, priciest: max_by(.price).name}'
Input
[{"name": "pen", "price": 2}, {"name": "book", "price": 15}, {"name": "mug", "price": 8}]
Output
{"cheapest":"pen","priciest":"book"}

Build a lookup table with reduce

Run

reduce folds an array into a single value, here an id-to-name map.

jq 'reduce .[] as $u ({}; .[$u.id] = $u.name)'
Input
[{"id": "u1", "name": "Alice"}, {"id": "u2", "name": "Bob"}]
Output
{"u1":"Alice","u2":"Bob"}

Strings and output formats

Text, CSV, Base64 and raw output.

String interpolation

Run

Embed expressions in strings with \(...).

jq -r '.[] | "\(.name) is \(.age) years old"'
Input
[{"name": "Alice", "age": 34}, {"name": "Bob", "age": 27}]
Output
Alice is 34 years old
Bob is 27 years old

Split and join strings

Run

split(sep) and join(sep) convert between strings and arrays.

jq '.path | split("/") | map(select(. != "")) | join(" > ")'
Input
{"path": "/usr/local/bin"}
Output
"usr > local > bin"

Convert JSON to CSV

Run

Build an array per row and format it with @csv; use raw output (-r).

jq -r '["name", "age"], (.[] | [.name, .age]) | @csv'
Input
[{"name": "Alice", "age": 34}, {"name": "Bob", "age": 27}]
Output
"name","age"
"Alice",34
"Bob",27

Turn an object into KEY=value lines

Run

to_entries exposes key/value pairs, handy for .env files.

jq -r 'to_entries[] | "\(.key)=\(.value)"'
Input
{"HOST": "localhost", "PORT": 8080}
Output
HOST=localhost
PORT=8080

Encode and decode Base64

Run

@base64 encodes a string, @base64d decodes it.

jq '{encoded: (.text | @base64), decoded: (.b64 | @base64d)}'
Input
{"text": "hello jq", "b64": "anNvbg=="}
Output
{"encoded":"aGVsbG8ganE=","decoded":"json"}

Parse a JSON string inside JSON

Run

fromjson parses an escaped JSON string; tojson does the opposite.

jq '.payload | fromjson | .id'
Input
{"payload": "{\"id\": 42, \"ok\": true}"}
Output
42

Convert a Unix timestamp to a date

Run

todate formats seconds since epoch as ISO 8601; strftime gives custom formats.

jq '.created | {iso: todate, day: strftime("%Y-%m-%d")}'
Input
{"created": 1700000000}
Output
{"iso":"2023-11-14T22:13:20Z","day":"2023-11-14"}

Advanced

Recursion, paths and multiple inputs.

List all leaf paths

Run

paths(f) returns the path to every value matching f; scalars matches leaves (but skips false and null).

jq '[paths(scalars) | map(tostring) | join(".")]'
Input
{"a": {"b": 1, "c": ["x", "y"]}}
Output
["a.b","a.c.0","a.c.1"]

Flatten nested arrays

Run

flatten removes nesting; pass a depth to flatten only some levels.

jq 'flatten'
Input
[1, [2, [3, [4]]]]
Output
[1,2,3,4]

Combine multiple JSON documents (slurp)

Run

With -s jq reads all inputs into one array, e.g. for NDJSON logs.

jq -s 'map(.ms) | add / length'
Input
{"ms": 120}
{"ms": 80}
{"ms": 100}
Output
100

Generate JSON without input

Run

With -n jq ignores input; useful for building JSON from scratch.

jq -n '[range(1; 4) | {id: ., label: "item-\(.)"}]'
Input
(none, -n)
Output
[{"id":1,"label":"item-1"},{"id":2,"label":"item-2"},{"id":3,"label":"item-3"}]

jq command-line options

The flags you can toggle in the playground, and what they do.

FlagLong formWhat it does
-r--raw-outputPrint strings without JSON quotes, e.g. for CSV or shell scripts.
-c--compact-outputPrint each JSON value on a single line.
-s--slurpRead every input value into one array before running the filter.
-n--null-inputIgnore the input and run the filter once with null.
-S--sort-keysSort the keys of every object in the output.

jq playground FAQ

Is this online jq playground free?

Yes. The jq playground is free, needs no account and has no usage limits. It is built by the author of the jq Playground extension for VS Code.

Is my JSON sent to a server?

No. jq 1.8.2 is compiled to WebAssembly and runs inside your browser, in a Web Worker. Your filter and JSON never leave your device, so you can safely test filters on private API responses or logs. Share links store the filter and input in the URL fragment, which browsers do not send to the server.

Which version of jq does the playground use?

The playground runs jq 1.8.2, the official jq source code compiled to WebAssembly with the jq-wasm package. Filters behave exactly like the jq command-line tool.

How is this different from jqplay?

jqplay.org is another popular online jq playground. This one runs jq entirely in your browser, lets you share a filter with a link, and comes with a cheat sheet of runnable jq examples. When you outgrow the browser, the same filters run in VS Code with the jq Playground extension.

Can I use jq with files, URLs or shell commands?

Not in the browser playground, which works on pasted JSON. The jq Playground extension for VS Code runs filters against workspace files, URLs and shell command output, and saves them in reusable .jqpg notebooks. See the VS Code extension →

Why does my filter stop after a few seconds?

To keep the page responsive, the playground stops a filter that runs for more than 3 seconds, which usually means an infinite generator such as repeat or range(infinite). Add limit(n; ...) or first(...) to take only the values you need.