jpx - JMESPath CLI with Extended Functions
A command-line tool for querying JSON data using JMESPath expressions with 400+ additional functions beyond the standard JMESPath specification.
Acknowledgments
jpx builds on the excellent work of the JMESPath community:
- JMESPath - The query language specification created by James Saryerwinnie
- jmespath.rs - The Rust implementation by @mtdowling that provides our parsing, evaluation, and standard functions
- jp - The official JMESPath CLI (Go) - a minimal, focused tool that inspired jpx's design
If you only need standard JMESPath without extensions, consider using jp or the jmespath crate directly.
jpx vs jq
Coming from jq? Here's a quick comparison:
| jq | jpx | |
|---|---|---|
| Language | Custom DSL | JMESPath (standardized) |
| Functions | ~70 built-in | 400+ extensions |
| Ecosystem | Standalone | Works with AWS CLI, Ansible |
| Streaming | ✅ | ❌ |
# jq # jpx
Choose jpx for: extended functions (geo, hash, fuzzy, semver), multiple output formats, AI/MCP integration, JMESPath ecosystem compatibility.
Choose jq for: streaming large files, custom function definitions, complex recursive transformations.
Quick Start (Docker)
Try jpx instantly without installing anything:
# Fetch a Hacker News story and extract fields
| \
# {"by": "pg", "score": 57, "title": "Y Combinator"}
# Basic query
|
# "Alice"
# Calculate average
|
# 85.0
# String manipulation
|
# "HELLO WORLD"
# Filter and transform
|
# ["alice"]
Installation
# Docker (no install needed)
# Homebrew (macOS/Linux)
# Pre-built binaries (macOS, Linux, Windows)
# Download from https://github.com/joshrotenberg/jpx/releases
# From crates.io
# From source
# Without MCP server support (smaller binary)
MCP Server (AI Assistant Integration)
For MCP (Model Context Protocol) support, use the dedicated jpx-mcp package:
# Install
# Or use Docker
See the MCP documentation for setup instructions with Claude Desktop.
Usage
) )
) )
)
)
Environment Variables
Configure jpx defaults via environment variables (CLI flags take precedence):
| Variable | Description |
|---|---|
JPX_VERBOSE=1 |
Enable verbose mode |
JPX_QUIET=1 |
Enable quiet mode |
JPX_STRICT=1 |
Enable strict mode (standard JMESPath only) |
JPX_RAW=1 |
Output raw strings without quotes |
JPX_COMPACT=1 |
Compact output (no pretty printing) |
# Set defaults in your shell profile
# Always output raw strings
# Temporarily use strict mode
JPX_STRICT=1
# Unset to use extensions again
Function Discovery
# List all available functions grouped by category
# Shows 26 standard JMESPath functions and 400+ extension functions
# List functions in a specific category
# Get detailed info about a specific function
# Shows type (standard JMESPath or extension), category, signature, and example
Examples
Basic Queries
# Simple field access
|
# "Alice"
# Array operations
|
# 15.0
# Nested access
|
# "alice@example.com"
Streaming (NDJSON/JSON Lines)
Process newline-delimited JSON one line at a time with constant memory usage. Perfect for large log files, event streams, and data pipelines.
# Basic streaming - each line is processed independently
|
# With raw output for piping to other tools
| |
# From a file
# Using the --each alias
|
# With expression functions
|
Performance: ~1.25 million lines/second (processes 100k lines in ~80ms)
How it works:
- Each line is parsed as a complete JSON object
- Expression is compiled once, reused for all lines
- Results output immediately (no accumulation)
- Empty lines and null results are skipped
- Errors on individual lines don't stop processing (use
-qto suppress)
Comparison with --slurp:
--slurploads all lines into memory as an array, then queries--streamprocesses each line independently with constant memory- Use
--slurpwhen you need to aggregate across lines (e.g.,sum([*].value)) - Use
--streamfor large files or when lines are independent
String Functions
# Case conversion
|
# "HELLO WORLD"
|
# "hello_world"
# String manipulation
|
# trim me
|
# hello, world
Array Functions
# Get unique values
|
# [1, 2, 3]
# Chunk arrays
|
# [[1, 2], [3, 4], [5, 6]]
# Array statistics
|
# 30.0
|
# 14.142135623730951
Date/Time Functions
# Current Unix timestamp
|
# 1705312200.0
# Format a Unix timestamp
|
# 2024-01-15
# Date arithmetic (add 7 days to timestamp)
|
# 1705881600.0
Duration Functions
# Parse human-readable durations
|
# 5400.0
|
# 60.0
# Format seconds as duration
|
# 1h2m5s
Color Functions
# Convert colors
|
# {"r": 255, "g": 85, "b": 0}
|
# #ff8000
# Color manipulation
|
# #5c85d6
|
# #00ffff
Computing Functions
# Parse byte sizes
|
# 1500000000.0
# Format bytes
|
# 1.00 GiB
# Bitwise operations
|
# 8
|
# 16
Hash and Encoding Functions
# Hash functions
|
# 5d41402abc4b2a76b9719d911017c592
|
# 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
# Base64 encoding
|
# aGVsbG8gd29ybGQ=
# URL encoding
|
# hello%20world%20%26%20more
Geo Functions
# Calculate distance between coordinates (km)
|
# 3935.746...
# Calculate bearing
|
# 273.687...
Network Functions
# IP address operations
|
# 3232235777
|
# true
|
# true
Semver Functions
# Parse semantic versions
|
# {"major": 1, "minor": 2, "patch": 3, "prerelease": "beta.1", "build": null}
# Compare versions
|
# -1
# Check version constraints
|
# true
Text Analysis Functions
# Word and character counts
|
# 6
|
# 12
# Reading time estimation
|
# "1 min read"
# Word frequencies
|
# {"the": 3, "quick": 1, "brown": 1, ...}
Phonetic Functions
# Soundex encoding
|
# R163
# Check if names sound alike
|
# true
# Double Metaphone
|
# {"primary": "SM0", "secondary": "XMT"}
Fuzzy Matching Functions
# Levenshtein distance
|
# 3
# Jaro-Winkler similarity
|
# 0.961...
# Sorensen-Dice coefficient
|
# 0.25
ID Generation Functions
# Generate UUIDs
|
# 550e8400-e29b-41d4-a716-446655440000
# Generate nanoids
|
# V1StGXR8_Z5jdHi6B-myT
# Generate ULIDs
|
# 01ARZ3NDEKTSV4RRFFQ69G5FAV
Validation Functions
# Email validation
|
# true
# URL validation
|
# true
# UUID validation
|
# true
# IP address validation
|
# true
Expression Functions (Higher-Order)
# Filter with expression reference
|
# [{"age": 25}, {"age": 30}]
# Map with expression reference
|
# ["Alice", "Bob"]
# Group by expression reference
|
# {"a": [{"type": "a", "v": 1}, {"type": "a", "v": 3}], "b": [{"type": "b", "v": 2}]}
Using Test Data Files
The testdata/ directory contains sample JSON files for experimenting:
# Users data
# Server logs
# E-commerce orders
# Geo locations
# Versions
Using Query Files
For complex queries, you can store the JMESPath expression in a file and use -Q / --query-file:
# Create a query file
# Run the query
Benefits of query files:
- Easier to write and edit complex expressions
- Can be version controlled
- Reusable across different data files
- No shell escaping issues
See the queries/ directory for example query files.
Tips
- Use
-r(raw) when piping string output to other commands - Use
-c(compact) for single-line JSON output - Use
--list-functionsto see all available functions - Backticks create literal values:
`5`is number 5,`"hello"`is string - Use
&prefix for expression references in higher-order functions
License
MIT OR Apache-2.0