{"id":13564648,"url":"https://github.com/tidwall/jj","last_synced_at":"2025-05-15T16:05:23.494Z","repository":{"id":44428798,"uuid":"71381721","full_name":"tidwall/jj","owner":"tidwall","description":"JSON Stream Editor (command line utility)","archived":false,"fork":false,"pushed_at":"2023-12-16T15:19:10.000Z","size":1262,"stargazers_count":2005,"open_issues_count":19,"forks_count":55,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-04-07T21:13:24.325Z","etag":null,"topics":["json","utility"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tidwall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-10-19T17:18:25.000Z","updated_at":"2025-04-04T08:42:29.000Z","dependencies_parsed_at":"2024-01-07T21:02:15.605Z","dependency_job_id":"fe8ccba0-0737-4d5d-9b1c-000215908bfc","html_url":"https://github.com/tidwall/jj","commit_stats":{"total_commits":56,"total_committers":4,"mean_commits":14.0,"dds":0.0535714285714286,"last_synced_commit":"c8ba809a3d44722beb888c266e9999fb89c6c6a9"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fjj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fjj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fjj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fjj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tidwall","download_url":"https://codeload.github.com/tidwall/jj/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374411,"owners_count":22060610,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","utility"],"created_at":"2024-08-01T13:01:34.022Z","updated_at":"2025-05-15T16:05:23.450Z","avatar_url":"https://github.com/tidwall.png","language":"Go","funding_links":[],"categories":["Go","json","\u003ca name=\"data-management-json\"\u003e\u003c/a\u003eData management - JSON/YAML/etc."],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg \n    src=\"logo.png\" \n    width=\"108\" height=\"78\" border=\"0\" alt=\"JJ\"\u003e\n\u003cbr\u003e\nJSON Stream Editor\n\u003c/p\u003e\n\nJJ is a command line utility that provides a [fast](#performance) and simple way to retrieve or update values from JSON documents.\nIt's powered by [GJSON](https://github.com/tidwall/gjson) and [SJSON](https://github.com/tidwall/sjson) under the hood. \n\nIt's [fast](#performance) 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.\n\nGetting started\n---------------\n\n## Install\n\n### Mac (Homebrew)\n\n```\nbrew install tidwall/jj/jj\n```\n\n### Build\n\n```\nmake\n```\n\nOr [download a pre-built binary](https://github.com/tidwall/jj/releases) for Linux, OSX, Windows, or FreeBSD.\n\n\n### Usage\n\n```\n$ jj -h\n\nusage: jj [-v value] [-purOD] [-i infile] [-o outfile] keypath\n\nexamples: jj keypath                      read value from stdin\n      or: jj -i infile keypath            read value from infile\n      or: jj -v value keypath             edit value\n      or: jj -v value -o outfile keypath  edit value and write to outfile\n\noptions:\n      -v value             Edit JSON key path value\n      -p                   Make json pretty, keypath is optional\n      -u                   Make json ugly, keypath is optional\n      -r                   Use raw values, otherwise types are auto-detected\n      -n                   Do not output color or extra formatting\n      -O                   Performance boost for value updates\n      -D                   Delete the value at the specified key path\n      -l                   Output array values on multiple lines\n      -i infile            Use input file instead of stdin\n      -o outfile           Use output file instead of stdout\n      keypath              JSON key path (like \"name.last\")\n```\n\n\nExamples\n--------\n\n### Getting a value \n\nJJ uses a [path syntax](https://github.com/tidwall/gjson#path-syntax) for finding values. \n\nGet a string:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj name.last\nSmith\n```\n\nGet a block of JSON:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj name\n{\"first\":\"Tom\",\"last\":\"Smith\"}\n```\n\nTry to get a non-existent key:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj name.middle\nnull\n```\n\nGet the raw string value:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -r name.last\n\"Smith\"\n```\n\nGet an array value by index:\n```sh\n$ echo '{\"friends\":[\"Tom\",\"Jane\",\"Carol\"]}' | jj friends.1\nJane\n```\n\n## JSON Lines\n\nThere's support for [JSON Lines](http://jsonlines.org/) using the `..` path prefix.\nWhich when specified, treats the multi-lined document as an array. \n\nFor example:\n\n```\n{\"name\": \"Gilbert\", \"age\": 61}\n{\"name\": \"Alexa\", \"age\": 34}\n{\"name\": \"May\", \"age\": 57}\n```\n\n```\n..#                   \u003e\u003e 4\n..1                   \u003e\u003e {\"name\": \"Alexa\", \"age\": 34}\n..#.name              \u003e\u003e [\"Gilbert\",\"Alexa\",\"May\"]\n..#[name=\"May\"].age   \u003e\u003e 57\n```\n\n### Setting a value\n\nThe [path syntax](https://github.com/tidwall/sjson#path-syntax) for setting values has a couple of tiny differences than for getting values.\n\nThe `-v value` option is auto-detected as a Number, Boolean, Null, or String. \nYou can override the auto-detection and input raw JSON by including the `-r` option.\nThis is useful for raw JSON blocks such as object, arrays, or premarshalled strings.\n\nUpdate a value:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -v Andy name.first\n{\"name\":{\"first\":\"Andy\",\"last\":\"Smith\"}}\n```\n\nSet a new value:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -v 46 age\n{\"age\":46,\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}\n```\n\nSet a new nested value:\n```sh\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -v relax task.today\n{\"task\":{\"today\":\"relax\"},\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}\n```\n\nReplace an array value by index:\n```sh\n$ echo '{\"friends\":[\"Tom\",\"Jane\",\"Carol\"]}' | jj -v Andy friends.1\n{\"friends\":[\"Tom\",\"Andy\",\"Carol\"]}\n```\n\nAppend an array:\n```sh\n$ echo '{\"friends\":[\"Tom\",\"Jane\",\"Carol\"]}' | jj -v Andy friends.-1\n{\"friends\":[\"Tom\",\"Andy\",\"Carol\",\"Andy\"]}\n```\n\nSet an array value that's past the bounds:\n```sh\n$ echo '{\"friends\":[\"Tom\",\"Jane\",\"Carol\"]}' | jj -v Andy friends.5\n{\"friends\":[\"Tom\",\"Andy\",\"Carol\",null,null,\"Andy\"]}\n```\n\nSet a raw block of JSON:\n```sh\n$ echo '{\"name\":\"Carol\"}' | jj -r -v '[\"Tom\",\"Andy\"]' friends\n{\"friends\":[\"Tom\",\"Andy\"],\"name\":\"Carol\"}\n```\n\nStart new JSON document:\n```sh\n$ echo '' | jj -v 'Sam' name.first\n{\"name\":{\"first\":\"Sam\"}}\n```\n\n### Deleting a value\n\nDelete a value:\n```sh\n$ echo '{\"age\":46,\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -D age\n{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}\n```\n\nDelete an array value by index:\n```sh\n$ echo '{\"friends\":[\"Andy\",\"Carol\"]}' | jj -D friends.0\n{\"friends\":[\"Carol\"]}\n```\n\nDelete last item in array:\n```sh\n$ echo '{\"friends\":[\"Andy\",\"Carol\"]}' | jj -D friends.-1\n{\"friends\":[\"Andy\"]}\n```\n\n### Optimistically update a value\n\nThe `-O` option can be used when the caller expects that a value at the\nspecified keypath already exists.\n\nUsing this option can speed up an operation by as much as 6x, but\nslow down as much as 20% when the value does not exist.\n\nFor example:\n\n```\necho '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -v Tim -O name.first\n```\n\nThe `-O` tells jj that the `name.first` likely exists so try a fasttrack operation first.\n\n## Pretty printing\n\nThe `-p` flag will make the output json pretty.\n\n```\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -p name\n{\n  \"first\": \"Tom\",\n  \"last\": \"Smith\"\n}\n```\n\nAlso the keypath is optional when the `-p` flag is specified, allowing for the entire json document to be made pretty.\n\n```\n$ echo '{\"name\":{\"first\":\"Tom\",\"last\":\"Smith\"}}' | jj -p\n{\n  \"name\": {\n    \"first\": \"Tom\",\n    \"last\": \"Smith\"\n  }\n}\n```\n\n## Ugly printing\n\nThe `-u` flag will compress the json into the fewest characters possible by squashing newlines and spaces.\n\n\n## Performance\n\nA quick comparison of jj to [jq](https://stedolan.github.io/jq/). The test [json file](https://github.com/tidwall/sf-city-lots-json) is 180MB file of 206,560 city parcels in San Francisco.\n\n*Tested on a 2015 Macbook Pro running jq 1.5 and jj 1.0.0*\n\n#### Get the lot number for the parcel at index 10000\n\njq:\n\n```bash\n$ time cat citylots.json | jq -cM .features[10000].properties.LOT_NUM\n\"091\"\n\nreal    0m5.486s\nuser    0m4.870s\nsys     0m0.686s\n```\n\njj:\n\n```bash\n$ time cat citylots.json | jj -r features.10000.properties.LOT_NUM\n\"091\"\n\nreal    0m0.354s\nuser    0m0.161s\nsys     0m0.321s\n```\n\n#### Update the lot number for the parcel at index 10000\n\njq:\n\n```bash\n$ time cat citylots.json | jq -cM '.features[10000].properties.LOT_NUM=\"12A\"' \u003e /dev/null\n\nreal    0m13.579s\nuser    0m16.484s\nsys     0m1.310s\n```\n\njj:\n\n```bash\n$ time cat citylots.json | jj -O -v 12A features.10000.properties.LOT_NUM \u003e /dev/null\n\nreal    0m0.431s\nuser\t0m0.201s\nsys     0m0.295s\n```\n\n## Contact\nJosh Baker [@tidwall](http://twitter.com/tidwall)\n\n## License\nJJ source code is available under the MIT [License](/LICENSE).\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fjj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftidwall%2Fjj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fjj/lists"}