Run jpx to query and transform JSON from the command line. Covers output formats (CSV, TSV, table, YAML), streaming NDJSON, input modes (slurp, raw-input, null-input), query files, variable binding, and shell pipelines. Use when building shell pipelines or exporting JSON data.
jpx is a JMESPath CLI with 460+ extended functions. It reads JSON, applies expressions, and outputs results in multiple formats.
# Expression as positional argument
echo '{"name":"alice"}' | jpx 'name'
# -> "alice"
# File input
jpx 'users[*].name' data.json
# Explicit file flag
jpx -f data.json 'users[*].name'
# Null input (no stdin needed)
jpx -n 'now()'
# Multiple expressions (chained pipeline)
jpx '[*].name' 'sort(@)' '[0]' data.json
# Same with -e flags
jpx -e '[*].name' -e 'sort(@)' -e '[0]' -f data.json
jpx 'expression' data.json # pretty-printed, colored
jpx -c 'expression' data.json # compact (one line)
jpx --indent 4 'expression' data.json # 4-space indent
jpx --tab 'expression' data.json # tab indent
jpx -S 'expression' data.json # sort object keys
jpx --color never 'expression' data.json # no color
jpx -r 'name' data.json # "alice" -> alice (no quotes)
jpx -j 'name' data.json # raw, no trailing newline
jpx --csv 'users[*]' data.json # CSV with headers from object keys
jpx --tsv 'users[*]' data.json # tab-separated
# Nested objects are flattened: {"addr":{"city":"NYC"}} -> addr.city column
jpx -t 'users[*]' data.json # formatted table
jpx -t --table-style ascii 'users[*]' data.json
# Styles: unicode (default), ascii, markdown, plain, rounded, sharp, modern
jpx -y 'config' data.json # YAML output
jpx --toml 'config' data.json # TOML output
jpx -l 'users[*]' data.json # one JSON value per line
jpx -o result.json 'expression' data.json
jpx --csv -o data.csv 'users[*]' data.json
-s)Combine multiple JSON values from stdin into a single array:
echo -e '{"id":1}\n{"id":2}\n{"id":3}' | jpx -s 'length(@)'
# -> 3
-R)Read each line as a JSON string (not parsed as JSON):
echo -e "hello\nworld" | jpx -R -s '[*] | sort(@)'
# -> ["hello", "world"]
-n)Use null as input, don't read stdin:
jpx -n 'now()' # current timestamp
jpx -n 'range(`1`, `11`)' # [1,2,...,10]
jpx -n 'uuid()' # random UUID
Process NDJSON line by line with constant memory:
# Each line processed independently
cat events.ndjson | jpx --stream 'user.name'
# Null results are automatically skipped
cat events.ndjson | jpx --stream '[?level == `error`] | [0]'
# Streaming with CSV output (headers from first record)
cat events.ndjson | jpx --stream --csv '{user: user.name, action: event}'
# Streaming with TSV
cat events.ndjson | jpx --stream --tsv '@'
# Unbuffered output (flush after each record)
tail -f events.ndjson | jpx --stream --unbuffered 'message'
Note: --stream is incompatible with --table, --yaml, --toml, and --lines (these need the full dataset). Use --slurp instead if you need those formats.
See references/streaming.md for more streaming patterns.
Bind variables for use in expressions:
# String variable
jpx --arg name Alice '[?name == $name]' data.json
# JSON variable (parsed)
jpx --argjson threshold 42 '[?score > $threshold]' data.json
jpx --argjson ids '[1,2,3]' '[?contains($ids, id)]' data.json
Save and reuse expressions with .jpx query files:
# Run a named query
jpx -Q queries.jpx:active-users data.json
# Alternative syntax
jpx -Q queries.jpx --query active-users data.json
# List available queries
jpx -Q queries.jpx --list-queries
# Validate queries without running
jpx -Q queries.jpx --check
See references/query-files.md for the .jpx file format.
jpx --list-functions # all 460+ functions
jpx --list-category String # functions in a category
jpx --describe format_date # detailed function info
jpx --search "date format" # fuzzy search
jpx --similar group_by # find related functions
jpx --stats -f data.json # type, size, depth analysis
jpx --paths -f data.json # all paths in dot notation
jpx --paths --types -f data.json # paths with types
jpx --paths --values -f data.json # paths with values
# Diff two files (RFC 6902 JSON Patch)
jpx --diff before.json after.json
# Apply a patch
jpx --patch changes.json -f original.json
# Merge (RFC 7396)
jpx --merge overlay.json -f base.json
# Explain expression (AST breakdown)
jpx --explain 'sort_by([*], &name) | [0]'
# Benchmark
jpx --bench 1000 'complex.expression' data.json
# Interactive REPL
jpx --repl -f data.json
jpx --repl --demo users # with demo dataset
# Exit status (for shell conditionals)
jpx -x '[?critical]' data.json && echo "found critical items"
# Fetch API, extract, and format as table
curl -s https://api.example.com/users | jpx -t '[*].{name: name, email: email}'
# Process log file, count errors by type
cat app.log | jpx --stream -s '[*]' | jpx 'group_by(@, &error_type)'
# Convert JSON to CSV for spreadsheet
jpx --csv 'records[*]' -o export.csv data.json
# Find largest files in package.json dependencies
jpx 'dependencies | keys(@) | sort(@)' package.json