An interactive, AI-augmented terminal tool for exploring JSON data. Think jq meets a code editor — with fuzzy search, tree navigation, schema inspection, and natural language querying.
cargo install jdxbrew install eladbash/jdx/jdxDownload from GitHub Releases — available for Linux, macOS, and Windows (x86_64 and aarch64).
git clone https://github.com/eladbash/jdx.git
cd jdx
cargo build --release
# Binary at: target/release/jdx# Configure AI providers interactively
jdx init
# Pipe JSON from stdin
echo '{"name": "Alice", "age": 30}' | jdx
# Explore an API response
curl -s https://api.github.com/repos/rust-lang/rust | jdx
# Open a file directly
jdx data.json
# YAML, TOML, CSV are auto-detected
cat config.yaml | jdxType a path like .users[0].name to drill into JSON data in real-time. Every keystroke updates the filtered view instantly.
Press Tab to see available keys at the current depth. Fuzzy matching ranks candidates so you can type "us" and match "users". Ghost text shows the most likely completion inline (like fish shell).
Press Ctrl+S for a split panel with a tree navigator on the left. Expand and collapse nodes with arrow keys. The query input and tree stay synchronized.
Press S to toggle schema view. Infers the shape of your JSON data — types, optional fields, value ranges, and array lengths — perfect for exploring unfamiliar API responses.
{
users: [object] # array of 3
count: number # 3
next_page: string | null
}
Filter arrays inline using bracket predicates:
.store.books[price < 10] # books cheaper than $10
.users[role == "admin"] # admin users only
.users[age >= 30] # users 30 and older
.items[status != "deleted"] # exclude deleted items
.users[active == true] # only active users
.items[deleted == null] # items without a deleted field
Supported operators: ==, !=, <, >, <=, >=
Values can be numbers (10, 3.5), quoted strings ("admin"), booleans (true/false), or null.
Compound filters with && (AND) and || (OR):
.items[price > 5 && price < 20] # price in range
.users[role == "admin" || role == "mod"] # multiple roles
.items[featured == true || price < 10 && stock > 0] # mixed (|| has lower precedence)
Filters can be combined with path navigation and transforms:
.store.books[price < 10].title # titles of cheap books
.store.books[price < 15] :pick title,price :sort price
.users[role == "admin"] :count # count admin users
Chain transforms after your query using : commands:
| Command | Description | Example |
|---|---|---|
:keys |
Object keys as array | .store :keys |
:values |
Object values as array | .store :values |
:count |
Count elements | .users :count |
:flatten |
Flatten nested arrays | .tags :flatten |
:pick |
Select fields | .users :pick name,email |
:omit |
Exclude fields | .users :omit metadata |
:sort |
Sort by field (asc/desc) | .users :sort age desc |
:uniq |
Deduplicate | .tags :uniq |
:group_by |
Group by field | .users :group_by role |
:filter |
Filter by predicate | .users :filter age > 30 |
:sum |
Sum numeric values | .orders :sum total |
:avg |
Average numeric values | .scores :avg value |
:min |
Minimum value | .products :min price |
:max |
Maximum value | .products :max price |
:reverse |
Reverse array or string | .users :reverse |
:upper |
Uppercase strings | .names :upper |
:lower |
Lowercase strings | .names :lower |
:split |
Split string by delimiter | .date :split - |
:join |
Join array with separator | .tags :join , |
The :filter transform supports compound expressions with && and ||:
.users :filter age > 20 && age < 40
.users :filter role == "admin" || role == "moderator"
Aggregate commands (:sum, :avg, :min, :max) work on arrays of numbers or on a specific field from objects:
.store.books :filter price < 10 :pick title,price
.users :pick name,age :filter age > 25 :sort age desc
.store.books :sum price # total of all book prices
.store.books :filter price < 15 :avg price # average of cheap books
.scores :min # minimum of a numeric array
String transforms can be chained together:
.date :split - :reverse :join / # "2024-01-15" → "15/01/2024"
.name :upper :split , :reverse :join , # chain multiple string ops
Press / to switch to AI mode. Ask questions in plain English:
"what is the total price of all books?" "which books cost less than $10?" "who are the admin users?"
The AI answers your question directly in natural language and optionally suggests a jdx query you can apply by pressing Enter. It sees the actual data, so it can compute totals, averages, find specific items, and more. Supports OpenAI, Anthropic, and local Ollama models.
Auto-detects JSON, YAML, TOML, CSV, and NDJSON input. Output in any format with --output:
cat config.yaml | jdx # YAML auto-detected
cat data.csv | jdx --input csv # CSV -> JSON
jdx data.json --output yaml # Output as YAMLPipe a streaming source and jdx launches immediately with the initial data, then updates live as new lines arrive. The status bar shows "(streaming...)" while data is still flowing.
tail -f logs.jsonl | jdx --input ndjson
docker logs -f myapp | jdx --input ndjson- Ctrl+Y — Copy current value to clipboard
- Ctrl+D — Bookmark the current path
Query history is saved across sessions. Press Ctrl+R to search through past queries.
| Key | Action |
|---|---|
| Tab | Complete / cycle candidates |
| Shift+Tab | Cycle candidates backward |
| Enter | Confirm and output result |
| Esc / Ctrl+C | Quit without output |
| Ctrl+L | Toggle key-only mode |
| Ctrl+U | Clear query |
| Ctrl+W | Delete word backward |
| Ctrl+A / Home | Cursor to start |
| Ctrl+E / End | Cursor to end |
| Ctrl+J | Scroll down |
| Ctrl+K | Scroll up |
| Ctrl+N | Page down |
| Ctrl+P | Page up |
| Ctrl+T | Scroll to top |
| Ctrl+G | Scroll to bottom |
| Ctrl+Y | Copy current value to clipboard |
| Ctrl+R | Search query history |
| Ctrl+D | Bookmark current path |
| Ctrl+S | Toggle split view (tree + JSON) |
| S | Toggle schema view |
| / | Switch to AI query mode |
| ? | Show help overlay |
| Key | Action |
|---|---|
| Up/Down | Navigate tree nodes |
| Right / Enter | Expand node |
| Left | Collapse node |
| Esc / q | Back to query mode |
| Key | Action |
|---|---|
| Type freely | Enter natural language question |
| Enter | Send question to AI / Apply suggested query |
| Esc | Back to query mode |
Configuration lives at ~/.config/jdx/config.toml:
[ai]
provider = "ollama" # "ollama", "openai", "anthropic", or "none"
model = "llama3.2" # Model name
api_key = "" # Required for cloud providers
endpoint = "" # Custom API endpoint (optional)
[display]
monochrome = false # Disable colors
max_candidates = 20 # Max items in autocomplete popup
schema_max_samples = 10 # Array elements to sample for schema inferenceLocal (Ollama):
# Install Ollama: https://ollama.ai
ollama pull llama3.2
# jdx auto-connects to localhost:11434Cloud (OpenAI):
[ai]
provider = "openai"
model = "gpt-4o-mini"
api_key = "sk-..."Usage: jdx [OPTIONS] [COMMAND] [FILE]
Commands:
init Run the interactive setup wizard to configure AI providers
Arguments:
[FILE] File to read JSON from (reads stdin if omitted)
Options:
-Q, --query <QUERY> Initial query (e.g., ".users[0]")
-q, --query-output Output the query string instead of the result
-i, --input <FORMAT> Input format: json, yaml, toml, csv, ndjson
-o, --output <FORMAT> Output format: json, yaml, toml, csv, ndjson
-M, --monochrome Disable colors
-p, --pretty Pretty-print output (default: true)
--non-interactive Evaluate query and print result without TUI
-h, --help Print help
-V, --version Print version
| Feature | jdx | jid | jq | fx | jless |
|---|---|---|---|---|---|
| Interactive TUI | Yes | Yes | No | Yes | Yes |
| Fuzzy completion | Yes | Prefix only | No | No | No |
| Tree navigation | Yes | No | No | No | Yes |
| Schema inspector | Yes | No | No | No | No |
| AI queries | Yes | No | No | No | No |
| Inline transforms | Yes | No | Yes (pipe) | Yes (JS) | No |
| Filter predicates | Yes | No | Yes | Yes (JS) | No |
| Multi-format input | Yes | No | No | Yes | No |
| Streaming NDJSON | Yes | No | Yes | Yes | No |
| Clipboard copy | Yes | No | No | No | No |
| Query history | Yes | No | No | No | No |
| Single binary | Yes | Yes | Yes | Yes | Yes |
| Written in | Rust | Go | C | Go | Rust |
# Clone and build
git clone https://github.com/eladbash/jdx.git
cd jdx
cargo build
# Run tests
cargo test
# Run with clippy
cargo clippy --all-targets --all-features -- -D warnings
# Format code
cargo fmt --allMIT
