The problem
Working with JSON in the terminal is painful. jq is powerful
but requires learning a whole query language. grep works but
matches values too — not just paths.
For example if I search for "name" in my JSON:
- grep matches
json.user.name✅ (correct) - grep also matches
json.bio = "my name is Alice"❌ (wrong)
So I built jray.
What jray does
jray flattens any JSON into one line per value:
$ jray data.json
json.organization.name = "Acme Corporation"
json.users[0].name = "Alice Pemberton"
json.users[0].role = "admin"
json.users[0].active = true
json.billing.plan = "enterprise"
Now you can grep it, awk it, pipe it — using tools you already know.
Four commands that cover everything
# Flatten with color output
jray data.json
# Fetch a URL directly — no curl needed
jray https://jsonplaceholder.typicode.com/users/1
# Filter by path only (never matches values)
jray data.json --filter "billing"
# Extract any subtree as clean JSON
jray data.json --select "billing"
# Print just the values
jray data.json --values
# Reconstruct original JSON
jray data.json | jray --ungron
The comparison with existing tools
| Feature | jray | jq | gron |
|---|---|---|---|
| Flatten to lines | ✅ | ❌ | ✅ |
| Reconstruct JSON | ✅ | ❌ | ✅ |
| Filter by path | ✅ | ✅ | ❌ |
| Extract subtree | ✅ | ✅ | ❌ |
| Fetch from URLs | ✅ | ❌ | ✅ |
| Color output | ✅ | ✅ | ✅ |
| No query language | ✅ | ❌ | ✅ |
| TypeScript / modern | ✅ | ❌ | ❌ |
What I learned building it
This was my first open source CLI tool. Key lessons:
1. Separate your CLI from your logic
cli.ts handles only I/O — reading files, printing output.
flatten.ts, filter.ts etc. know nothing about terminals.
This makes everything testable in isolation.
2. Use unknown not any in TypeScript
JSON is dynamic but that doesn't mean any. Using unknown
forces you to check types before using values — much safer.
3. Recursive functions are perfect for JSON
JSON is a tree. Walking a tree with recursion is the
cleanest pattern — each call handles one node and
delegates children back to itself.
4. Bun is genuinely fast and simple
Native TypeScript, built-in fetch, fast startup.
For a CLI tool, Bun is a great choice.
5. The README matters as much as the code
Nobody uses a tool they can't understand in 30 seconds.
Writing clear examples with real output is as important
as writing the code itself.
Install and try it
npm install -g @siyadkc/jray
Then:
jray https://jsonplaceholder.typicode.com/users/1
GitHub: github.com/siyadhkc/Jray
for more info Website: https://siyadhkc.github.io/Jray/
This is my first open source tool. Feedback on the code
quality is very welcome — especially from experienced
TypeScript developers!
Top comments (0)