Top Related Projects
Command-line JSON processor
Terminal JSON viewer & processor
json incremental digger
Make JSON greppable!
yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
Select, put and delete data from JSON, TOML, YAML, XML and CSV files with a single tool. Supports conversion between formats and can be used as a Go package.
Quick Overview
JJ is a command-line JSON processor written in Go. It provides a fast and efficient way to manipulate JSON data from the terminal, offering features like querying, modifying, and formatting JSON structures.
Pros
- Fast performance due to its implementation in Go
- Supports a wide range of JSON manipulation operations
- Easy-to-use command-line interface
- Can handle large JSON files efficiently
Cons
- Limited documentation compared to some other JSON processing tools
- May require learning a specific syntax for complex operations
- Not as feature-rich as some more established JSON processing libraries
- Primarily focused on command-line usage, which may not suit all use cases
Code Examples
- Basic JSON querying:
package main
import "github.com/tidwall/jj"
func main() {
json := `{"name":"John","age":30,"city":"New York"}`
result := jj.Get(json, "name")
println(result.String()) // Output: John
}
- Modifying JSON:
package main
import "github.com/tidwall/jj"
func main() {
json := `{"name":"John","age":30,"city":"New York"}`
result := jj.Set(json, "age", 31)
println(result) // Output: {"name":"John","age":31,"city":"New York"}
}
- Deleting a JSON key:
package main
import "github.com/tidwall/jj"
func main() {
json := `{"name":"John","age":30,"city":"New York"}`
result := jj.Delete(json, "city")
println(result) // Output: {"name":"John","age":30}
}
Getting Started
To use JJ in your Go project, first install it:
go get -u github.com/tidwall/jj
Then, import it in your Go code:
import "github.com/tidwall/jj"
You can now use JJ functions to process JSON data in your Go applications. For command-line usage, refer to the project's README for installation and usage instructions.
Competitor Comparisons
Command-line JSON processor
Pros of jq
- More mature and widely adopted project with extensive documentation
- Supports a broader range of JSON manipulation operations
- Has a larger community and ecosystem of extensions
Cons of jq
- Written in C, which may be less accessible for some contributors
- Can be more complex to use for simple operations
- Slower performance for certain operations compared to jj
Code Comparison
jq:
jq '.[] | select(.name == "Alice") | .age'
jj:
jj -i 'name == "Alice"' age
Both tools aim to process JSON data, but jq offers a more comprehensive set of features and a domain-specific language for JSON manipulation. jj, on the other hand, focuses on simplicity and speed, providing a more straightforward command-line interface for common JSON operations.
jq excels in complex JSON transformations and filtering, while jj is designed for quick and efficient JSON querying and modification. The choice between the two depends on the specific use case, with jq being more suitable for advanced JSON processing tasks and jj offering a simpler alternative for basic operations with potentially better performance.
Terminal JSON viewer & processor
Pros of fx
- More feature-rich with interactive mode and support for various data formats
- Actively maintained with frequent updates and contributions
- Extensive documentation and examples for ease of use
Cons of fx
- Larger codebase and dependencies, potentially slower startup time
- May be overkill for simple JSON processing tasks
- Steeper learning curve due to more advanced features
Code Comparison
fx:
fx '.[0].name' data.json
fx 'map(x => x.toUpperCase())' data.json
jj:
jj -i data.json '.[0].name'
echo '["hello", "world"]' | jj 'map(strings.upper)'
Summary
fx is a more comprehensive JSON processing tool with interactive features and support for multiple data formats. It offers a rich set of functionalities but may be more complex for simple tasks. jj, on the other hand, is a lightweight and fast JSON processor focused on simplicity and ease of use for basic JSON manipulation. The choice between the two depends on the specific requirements of the task at hand and the user's preference for simplicity versus advanced features.
json incremental digger
Pros of jid
- Written in Go, which may be more familiar to some developers
- Supports interactive JSON editing and manipulation
- Provides a more user-friendly interface for JSON exploration
Cons of jid
- Less actively maintained (last commit over 3 years ago)
- Fewer features compared to jj
- Limited to JSON format only
Code Comparison
jid:
func (e *Engine) Run() {
e.initReader()
e.printJSON()
e.queryLoop()
}
jj:
func (j *JJ) Run() {
j.loadInput()
j.processCommands()
j.outputResult()
}
Both projects aim to provide JSON processing capabilities, but they differ in their approach and feature set. jj offers a more comprehensive set of features, including support for multiple data formats (JSON, YAML, TOML), while jid focuses specifically on interactive JSON exploration.
jj is more actively maintained and has a larger community, which may lead to better long-term support and feature development. However, jid's simplicity and focus on JSON manipulation might be preferable for users who primarily work with JSON and desire a straightforward, interactive tool.
The code comparison shows that both projects have similar high-level structures for their main execution flow, but the implementation details differ based on their specific features and design choices.
Make JSON greppable!
Pros of gron
- Simpler syntax and easier to learn for beginners
- Better integration with Unix command-line tools
- More focused on flattening JSON for grep-like operations
Cons of gron
- Less powerful query capabilities compared to jj
- Limited to JSON input, while jj supports multiple formats
- Lacks advanced features like in-place editing and formatting
Code comparison
gron:
gron input.json | grep "name" | gron --ungron
jj:
jj -i input.json 'name'
Summary
gron is a straightforward tool for flattening JSON into greppable format, making it ideal for quick searches and simple transformations. It excels in Unix-style workflows and is easy to pick up for those familiar with command-line tools.
jj, on the other hand, offers a more comprehensive JSON manipulation toolkit with support for various input formats, advanced querying, and in-place editing. While it has a steeper learning curve, jj provides more flexibility and power for complex JSON operations.
Choose gron for simple JSON flattening and grep-like searches, or opt for jj when you need more advanced JSON manipulation capabilities and support for multiple formats.
yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
Pros of yq
- Specifically designed for YAML processing, offering more YAML-centric features
- Supports multiple input formats (JSON, YAML, XML, properties) and can convert between them
- More extensive documentation and examples available
Cons of yq
- Limited to YAML and related formats, less versatile for general-purpose JSON manipulation
- May have a steeper learning curve for users not familiar with YAML-specific concepts
Code comparison
yq:
yq e '.users[] | select(.age > 30)' input.yaml
jj:
jj -i input.json '.users | map(select(.age > 30))'
Key differences
- yq is primarily focused on YAML processing, while jj is designed for JSON manipulation
- jj offers a more lightweight and faster solution for JSON-specific tasks
- yq provides broader format support and conversion capabilities
- jj's syntax is more closely aligned with jq, making it familiar to jq users
- yq has a larger community and more frequent updates
Both tools have their strengths, with yq excelling in YAML-centric workflows and jj offering a streamlined JSON processing experience. The choice between them depends on the specific requirements of your project and the primary data format you're working with.
Select, put and delete data from JSON, TOML, YAML, XML and CSV files with a single tool. Supports conversion between formats and can be used as a Go package.
Pros of dasel
- Supports a wider range of data formats (JSON, YAML, TOML, XML, CSV)
- Offers both reading and writing capabilities
- Provides a more extensive set of commands and options
Cons of dasel
- Generally slower performance compared to jj
- More complex syntax for some operations
- Larger binary size and resource footprint
Code comparison
dasel:
dasel -f data.json '.users.[].name'
dasel put string -f data.json '.users.[0].name' 'John'
jj:
jj -i data.json users.*.name
echo '{"users":[{"name":"John"}]}' | jj users.0.name John
Summary
dasel offers more versatility in terms of supported formats and operations, making it suitable for complex data manipulation tasks across various file types. However, jj excels in simplicity and performance, particularly for JSON-specific operations. The choice between the two depends on the specific requirements of the project, with dasel being more feature-rich and jj being more lightweight and focused on JSON processing.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
JSON Stream Editor
JJ is a command line utility that provides a fast and simple way to retrieve or update values from JSON documents. It's powered by GJSON and SJSON under the hood.
It's fast because it avoids parsing irrelevant sections of json, skipping over values that do not apply, and aborts as soon as the target value has been found or updated.
Getting started
Install
Mac (Homebrew)
brew install tidwall/jj/jj
Build
make
Or download a pre-built binary for Linux, OSX, Windows, or FreeBSD.
Usage
$ jj -h
usage: jj [-v value] [-purOD] [-i infile] [-o outfile] keypath
examples: jj keypath read value from stdin
or: jj -i infile keypath read value from infile
or: jj -v value keypath edit value
or: jj -v value -o outfile keypath edit value and write to outfile
options:
-v value Edit JSON key path value
-p Make json pretty, keypath is optional
-u Make json ugly, keypath is optional
-r Use raw values, otherwise types are auto-detected
-n Do not output color or extra formatting
-O Performance boost for value updates
-D Delete the value at the specified key path
-l Output array values on multiple lines
-i infile Use input file instead of stdin
-o outfile Use output file instead of stdout
keypath JSON key path (like "name.last")
Examples
Getting a value
JJ uses a path syntax for finding values.
Get a string:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name.last
Smith
Get a block of JSON:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name
{"first":"Tom","last":"Smith"}
Try to get a non-existent key:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name.middle
null
Get the raw string value:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -r name.last
"Smith"
Get an array value by index:
$ echo '{"friends":["Tom","Jane","Carol"]}' | jj friends.1
Jane
JSON Lines
There's support for JSON Lines using the ..
path prefix.
Which when specified, treats the multi-lined document as an array.
For example:
{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}
..# >> 4
..1 >> {"name": "Alexa", "age": 34}
..#.name >> ["Gilbert","Alexa","May"]
..#[name="May"].age >> 57
Setting a value
The path syntax for setting values has a couple of tiny differences than for getting values.
The -v value
option is auto-detected as a Number, Boolean, Null, or String.
You can override the auto-detection and input raw JSON by including the -r
option.
This is useful for raw JSON blocks such as object, arrays, or premarshalled strings.
Update a value:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v Andy name.first
{"name":{"first":"Andy","last":"Smith"}}
Set a new value:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v 46 age
{"age":46,"name":{"first":"Tom","last":"Smith"}}
Set a new nested value:
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v relax task.today
{"task":{"today":"relax"},"name":{"first":"Tom","last":"Smith"}}
Replace an array value by index:
$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.1
{"friends":["Tom","Andy","Carol"]}
Append an array:
$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.-1
{"friends":["Tom","Andy","Carol","Andy"]}
Set an array value that's past the bounds:
$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.5
{"friends":["Tom","Andy","Carol",null,null,"Andy"]}
Set a raw block of JSON:
$ echo '{"name":"Carol"}' | jj -r -v '["Tom","Andy"]' friends
{"friends":["Tom","Andy"],"name":"Carol"}
Start new JSON document:
$ echo '' | jj -v 'Sam' name.first
{"name":{"first":"Sam"}}
Deleting a value
Delete a value:
$ echo '{"age":46,"name":{"first":"Tom","last":"Smith"}}' | jj -D age
{"name":{"first":"Tom","last":"Smith"}}
Delete an array value by index:
$ echo '{"friends":["Andy","Carol"]}' | jj -D friends.0
{"friends":["Carol"]}
Delete last item in array:
$ echo '{"friends":["Andy","Carol"]}' | jj -D friends.-1
{"friends":["Andy"]}
Optimistically update a value
The -O
option can be used when the caller expects that a value at the
specified keypath already exists.
Using this option can speed up an operation by as much as 6x, but slow down as much as 20% when the value does not exist.
For example:
echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v Tim -O name.first
The -O
tells jj that the name.first
likely exists so try a fasttrack operation first.
Pretty printing
The -p
flag will make the output json pretty.
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -p name
{
"first": "Tom",
"last": "Smith"
}
Also the keypath is optional when the -p
flag is specified, allowing for the entire json document to be made pretty.
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -p
{
"name": {
"first": "Tom",
"last": "Smith"
}
}
Ugly printing
The -u
flag will compress the json into the fewest characters possible by squashing newlines and spaces.
Performance
A quick comparison of jj to jq. The test json file is 180MB file of 206,560 city parcels in San Francisco.
Tested on a 2015 Macbook Pro running jq 1.5 and jj 1.0.0
Get the lot number for the parcel at index 10000
jq:
$ time cat citylots.json | jq -cM .features[10000].properties.LOT_NUM
"091"
real 0m5.486s
user 0m4.870s
sys 0m0.686s
jj:
$ time cat citylots.json | jj -r features.10000.properties.LOT_NUM
"091"
real 0m0.354s
user 0m0.161s
sys 0m0.321s
Update the lot number for the parcel at index 10000
jq:
$ time cat citylots.json | jq -cM '.features[10000].properties.LOT_NUM="12A"' > /dev/null
real 0m13.579s
user 0m16.484s
sys 0m1.310s
jj:
$ time cat citylots.json | jj -O -v 12A features.10000.properties.LOT_NUM > /dev/null
real 0m0.431s
user 0m0.201s
sys 0m0.295s
Contact
Josh Baker @tidwall
License
JJ source code is available under the MIT License.
Top Related Projects
Command-line JSON processor
Terminal JSON viewer & processor
json incremental digger
Make JSON greppable!
yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
Select, put and delete data from JSON, TOML, YAML, XML and CSV files with a single tool. Supports conversion between formats and can be used as a Go package.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot