Use FindUtils JQ Playground to try a supported subset of jq-style expressions against JSON. Start with a field selector or simple filter. Confirm the result with your actual jq version before you use a query in a script.
jq is a lightweight command-line JSON processor often called "sed for JSON." It lets developers slice, filter, map, and transform structured data with a concise query language that's purpose-built for JSON. This guide walks you through the fundamentals, practical examples, and advanced patterns — with a separate limit for expressions the playground does not implement.
What Is jq and Why Should You Learn It?
jq is a domain-specific language designed exclusively for querying and transforming JSON data. It's one of the most widely used tools in the developer ecosystem: installed by default on many Linux distributions, referenced in thousands of Stack Overflow answers, and used daily by DevOps engineers, backend developers, and data analysts.
Here's why jq matters:
- Conciseness — Extract a list of names from an array of objects with
.users | map(.name)instead of writing 10 lines of Python or JavaScript - Composability — Chain operations with the pipe operator (
|) to build complex transformations from simple building blocks - Zero dependencies — jq has no runtime dependencies; the online playground runs entirely in your browser
- JSON input — Start with a small valid document. Depth, file size, and supported expression syntax limit practical use
- Script-friendly — Perfect for CI/CD pipelines, shell scripts, and automated data processing
Unlike general-purpose languages, jq makes common JSON operations — filtering, mapping, grouping, aggregating — trivially easy. A transformation that takes 15 lines in Python takes a single jq expression.
How to Use the JQ Playground Online (Step by Step)
Step 1: Open the Playground and Load JSON Data
Navigate to the FindUtils JQ Playground. You'll see two panels: JSON Input on the left and Result on the right. Paste your JSON data into the input panel, or click Load Example to start with sample data containing users, metadata, and nested objects.
You can also drag and drop a .json file directly into the input panel. The playground accepts any valid JSON — objects, arrays, strings, or numbers.
Step 2: Write Your jq Expression
Type your jq expression in the query bar at the top of the page. Start with the simplest expression — a single dot (.) — which returns the entire input unchanged. Then build up:
.users— Access the "users" field.users[0]— Get the first user.users | length— Count the number of users.users | map(.name)— Extract all names as an array
Results update in real-time as you type. The execution time is displayed next to the query bar so you can gauge performance.
Step 3: Explore Built-In Examples
Click the Examples button to browse categorized jq queries. The examples cover:
- Basics — Field access, array indexing, identity
- Filtering —
select(), conditional logic, null handling - Transform —
map(), object construction, field renaming - Other supported operations —
group_by()andto_entries/from_entries;reducerequires a full jq runtime
Click any example to load it instantly into the query bar.
Step 4: Use the Cheat Sheet for Quick Reference
Click Cheat Sheet for a categorized quick-reference card covering pipes, filters, construction syntax, array operations, math/logic, and string functions. It's designed for developers who know jq basics but need a syntax reminder.
Step 5: Save and Export Results
Press Enter after writing an expression to save it to your query history. You can revisit previous expressions by clicking the History button. To export results, use the Copy button or Download JSON to save the output as a .json file.
Essential jq Syntax: A Practical Reference
The following syntax covers common selection and transformation patterns. Here are the operations you'll use most.
Field Access and Navigation
| Expression | Description | Example Output |
|---|---|---|
. | Identity — returns entire input | {...} |
.name | Access a single field | "John" |
.address.city | Access nested fields | "New York" |
.users[0] | First array element | {"name":"John",...} |
.users[-1] | Last array element | {"name":"Jane",...} |
.users[1:3] | Array slice (index 1 and 2) | [{...},{...}] |
.users[].name | All names from array | "John" "Jane" ... |
Filtering with select()
The select() function is jq's primary filtering mechanism. It keeps elements that match a condition and discards everything else.
.users | map(select(.age > 25)) # Users older than 25
.items | map(select(.active == true)) # Only active items
.logs | map(select(.level == "error")) # Only error logs
.users | map(select(.name | test("^A"))) # Names starting with "A"Combine multiple conditions with and/or:
.users | map(select(.age > 20 and .active == true))
Transforming with map()
The map() function applies an expression to every element in an array. Use it to reshape data.
.users | map(.name) # Extract names → ["John","Jane"]
.users | map({name, email}) # Keep only name + email
.users | map({full_name: .name, mail: .email}) # Rename fields
.users | map(. + {role: "member"}) # Add a field to each objectPipes: Chaining Operations
The pipe operator (|) is jq's most powerful feature. It passes the output of one operation as input to the next — just like Unix pipes.
.users | select(.active) | map(.name) | sort
This reads as: get users → keep only active ones → extract names → sort alphabetically. Each pipe stage is independent, making complex queries easy to build and debug incrementally.
Aggregation Functions
| Function | Description | Example |
|---|---|---|
length | Count elements or string length | .users | length → 5 |
add | Sum numbers or concatenate strings | [1,2,3] | add → 6 |
min / max | Find minimum or maximum | .prices | max → 99.99 |
unique | Remove duplicates | [1,2,2,3] | unique → [1,2,3] |
group_by(.field) | Group array by field value | Groups users by department |
sort_by(.field) | Sort array by field | .users | sort_by(.age) |
Real-World jq Use Cases
Processing API Responses
REST APIs return JSON, and jq makes extracting the data you need trivial. Suppose you call a GitHub API endpoint that returns repository data:
# Get all repository names
.[] | .name
# Get repos with more than 100 stars
map(select(.stargazers_count > 100)) | map({name, stars: .stargazers_count})
# Find the most-starred repo
max_by(.stargazers_count) | {name, stars: .stargazers_count}Test these expressions in the JQ Playground by pasting any API response into the input panel.
Filtering Log Files
JSON-formatted logs (common with structured logging) are perfect for jq analysis:
# Get only error-level logs
.[] | select(.level == "error")
# Count errors per service
group_by(.service) | map({service: .[0].service, errors: length})
# Find errors from the last hour
map(select(.timestamp > "2026-02-19T11:00:00Z" and .level == "error"))Data Transformation for Import/Export
Reshape JSON for different systems:
# Convert array of objects to key-value map
map({key: .id | tostring, value: .name}) | from_entries
# Flatten nested structure
.departments[].employees[] | {dept: .department, name: .name}
# Create CSV-ready format
.users | map([.name, .email, (.age | tostring)] | join(","))Configuration File Queries
Extract values from complex config files:
# Get all database connection strings
.databases | to_entries | map({name: .key, host: .value.host})
# Find services running on port 8080
.services | to_entries | map(select(.value.port == 8080)) | map(.key)jq vs JSONPath: Which Should You Use?
Both jq and JSONPath query JSON, but they serve fundamentally different purposes. jq is a full programming language; JSONPath is a selection syntax.
| Feature | jq | JSONPath |
|---|---|---|
| Type | Full programming language | Query/selection syntax |
| Transform data | Yes — map, reduce, construct new objects | No — selection only |
| Aggregate | Yes — sum, min, max, group_by | No |
| Pipes | Yes — chain filters | No |
| Conditionals | Yes — if/then/else, select() | Limited |
| String operations | Yes — split, join, test (regex), ltrimstr | No |
| Create new JSON | Yes — construct arbitrary output | No |
| Learning focus | Filters and transformations | Paths and selectors |
| Best for | Data processing, scripting, CI/CD | Simple field extraction |
Recommendation: Use jq when you need to transform, aggregate, or reshape JSON. Use JSONPath (available in FindUtils' JSON Path Finder) when you just need to locate and extract specific values from a structure.
JQ Playgrounds: capabilities and limits
| Capability | FindUtils |
|---|---|
| Built-in examples | 30+ categorized examples |
| Cheat sheet | Embedded in playground |
| Query history | Yes — 20 recent queries |
| Operations reference | Yes — 20+ operations listed |
| File upload | Drag & drop JSON files |
| Output export | Copy + JSON download |
| Execution timing | Displayed per query |
| Snippet sharing | No |
| AI assistance | No |
| jq flags (compact, slurp) | No |
| Mobile-friendly | Yes |
FindUtils' JQ Playground is optimized for learning and everyday use: built-in examples, a cheat sheet, query history, and file upload make it an option for developers who want to test jq expressions quickly. Use the official jq documentation and a full jq runtime for command-line flags or unsupported expressions.
Common jq Mistakes and How to Fix Them
Mistake 1: Forgetting to Iterate Arrays
Wrong: .users.name (tries to access .name on an array — fails)
Right: .users[].name or .users | map(.name)
Arrays need explicit iteration. Use .[] to iterate or map() to transform each element.
Mistake 2: Confusing map() and select()
map() transforms every element. select() filters elements by condition. To filter AND transform, combine them:
.users | map(select(.active)) | map(.name) # Or more concisely: .users | map(select(.active) | .name)
Mistake 3: Not Handling null Values
jq returns null for missing fields rather than throwing an error. Use the alternative operator (//) to provide defaults:
.users | map(.nickname // .name) # Use nickname, fall back to name .config.timeout // 30 # Default to 30 if missing
Mistake 4: Using Quotes Incorrectly
Field names with special characters need bracket notation:
# Wrong (if field has hyphens): .content-type # Right: .["content-type"]
String values in conditions need double quotes inside the expression:
select(.status == "active") # Correct select(.status == active) # Wrong — "active" is interpreted as a function
Mistake 5: Expecting Array Output from .[]
The .[] operator produces a stream of values, not an array. Wrap in [...] to collect results back into an array:
[.users[].name] # Array of names .users | [.[] | select(.active)] # Array of active users
jq Quick Reference Cheat Sheet
Basics
. # Identity (entire input) .field # Object field access .field? # Field access (suppress errors) .a.b.c # Nested access
Arrays
.[0] # First element .[-1] # Last element .[2:5] # Slice (index 2,3,4) .[] | .name # Iterate and extract [.[] | ...] # Collect results into array
Pipes & Filters
.a | .b # Pipe (chain operations) select(condition) # Keep matching elements map(expression) # Transform each element empty # Produce no output
Construction
{name, age} # Shorthand: {name: .name, age: .age}
{n: .name, a: .age} # Rename fields
[.[] | .name] # Build array from streamAggregation
length # Array length or string length add # Sum numbers / join strings min, max # Minimum / maximum unique # Remove duplicates group_by(.field) # Group by field value sort_by(.field) # Sort by field value
String Operations
split(",") # Split string by delimiter
join(",") # Join array into string
test("regex") # Test regex match (boolean)
ascii_downcase # Lowercase
ascii_upcase # Uppercase
ltrimstr("prefix") # Remove prefixTools Used in This Guide
- JQ Playground — Test and debug jq expressions in your browser with real-time results, examples, and a cheat sheet
- JSON Formatter — Pretty-print and validate JSON before feeding it into jq queries
- JSON Path Finder — Locate values in complex JSON structures using JSONPath syntax
- JSON Visualizer — Visualize JSON structure as an interactive tree to understand nested data
- JSON Diff — Compare two JSON documents to spot differences after jq transformations
Playground limits and the jq reference
The browser engine is a subset. It does not implement reduce, try, foreach, recursive descent (..), or user-defined functions. General jq examples that use those features belong in a full jq runtime.
A result in this playground does not establish jq compatibility. For example, the local sort operation uses JavaScript sorting, which can order numbers differently from jq. Use the official jq manual to check language behavior. Keep the same input and expected output when you compare implementations.
FAQ
Q1: What is a jq playground and how does it work? A: A jq playground is a browser-based tool that lets you test jq expressions against JSON data in real time. Paste your JSON, write a jq filter, and see the output instantly — no installation needed. FindUtils' JQ Playground performs the described operation in the browser, without a separate upload of the supplied JSON.
Q2: Is the FindUtils JQ Playground free to use? A: Yes. FindUtils' JQ Playground is available without signup. All processing happens locally in your browser — no data is uploaded to any server.
Q3: Can I use jq without installing it on my computer? A: Yes. Online jq playgrounds let you run jq expressions directly in your browser. FindUtils' JQ Playground supports the most commonly used jq operations including map, select, sort_by, group_by, to_entries, and more — all without installing anything.
Q4: When should I use this jq playground?
A: It includes 30+ built-in examples, an embedded cheat sheet, query history, drag-and-drop file upload, and JSON download — all with local processing. The official play.jqlang.org is another solid option for users who need advanced flags like --slurp or --raw-input.
Q5: How do I filter a JSON array with jq?
A: Use the select() function inside map(). For example, .users | map(select(.age > 25)) returns only users older than 25. You can combine conditions: map(select(.active == true and .role == "admin")). Test your filters instantly in the JQ Playground.
Q6: What is the difference between jq and JSONPath? A: JSONPath is a query language for selecting nodes from JSON, similar to XPath for XML. jq is a full programming language that can select, transform, aggregate, and construct entirely new JSON structures. jq supports pipes, functions, conditionals, and reduce operations — making it far more powerful than JSONPath for data processing tasks.
Q7: Is it safe to paste sensitive JSON data into an online jq playground? A: Use example input in JQ Playground. Check the output before you share it or use it in another application.
Q8: What jq operations does the FindUtils playground support?
A: The playground supports field access, array indexing and slicing, pipe operations, map, select, sort_by, group_by, unique, flatten, keys, values, to_entries, from_entries, has, contains, del, string operations (split, join, test), math operations, and object construction. For advanced features like recursive descent (..) or custom function definitions, use the full jq command-line tool.
Next Steps
- The Complete Guide to Online JSON Tools — Explore the full suite of JSON tools for formatting, validation, comparison, and conversion
- How to Compare Two JSON Files Online — Learn to diff JSON documents after transforming them with jq
- JSON Schema Validation Explained — Validate your jq output against schemas to ensure data integrity
- JSON Conversion Tools Online — Convert jq output to CSV, XML, TypeScript, and more