gjson

Fast, dependency-light JSON value extraction for Go using dot-notation paths.

Library
Go
vv1.20.0
15,554 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
68 /100 Good
Development Activity 68
Maintenance 24
Community 80
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
70 /100 Good
Architecture 75
Code Quality 68
Innovation 72
Learning Curve 65

GJSON is a small, dependency-light Go library for reading values out of JSON strings and byte slices using a compact dot-notation path syntax. Instead of defining a struct and unmarshaling an entire payload, callers call gjson.Get(json, “friends.#(last==“Murphy”).first”) and get back a typed Result, with array queries, wildcards, and pipe-chained modifiers like @pretty and @reverse handled directly in the path string.

It has been in active development since 2016, ships a documented path-syntax reference (SYNTAX.md), pairs with a sibling library (SJSON) for writing values back into JSON, and includes a zero-copy GetBytes path aimed at services that parse large payloads on a hot path.

What You Get

  • Path-based value extraction (Get/GetBytes) that works directly on strings or byte slices without allocating a target struct.
  • Array query syntax (#(...), #(...)#) with comparison and pattern-matching operators for filtering nested arrays inline.
  • A library of pipe-chained modifiers (@pretty, @ugly, @reverse, @flatten, @group, @dig, @keys, @values) for reshaping results without extra code.
  • JSON Lines iteration (ForEachLine, the .. path prefix) for newline-delimited JSON documents.
  • A Result type with typed accessors (String/Int/Float/Bool/Time/Array/Map) plus Index/Indexes for locating matches in the source text.

Common Use Cases

  • Trimming large third-party API responses down to the handful of fields a service actually needs, without a matching struct.
  • Processing newline-delimited JSON logs with ForEachLine and the .. path prefix instead of a custom line-by-line unmarshal loop.
  • Inspecting or reshaping JSON with an unknown or dynamic schema, where path queries replace repeated map[string]interface{} type assertions.
  • Reading a handful of keys out of a larger JSON config file at startup without maintaining a full config struct.

Under The Hood

Architecture

The entire library lives in one flat file (gjson.go, ~3,700 lines) plus a companion test file, with the only two dependencies being tidwall/match (pattern matching for query filters) and tidwall/pretty (the @pretty/@ugly modifiers), both by the same author. Get(json, path) splits the dot-path via parseObjectPath/parseArrayPath, then parseObject/parseArray walk the raw JSON string byte-by-byte matching path segments without building an intermediate AST, returning Result structs whose Raw/Str/Num fields are sliced directly from the original input. Parsing and path-matching are deliberately fused into the same recursive walk rather than split into separate layers, which favors speed over modularity — changing the Result or path-parsing contract would touch most of the file.

Tech Stack

Written in Go (module targets go 1.23, and uses the newer iter package for range-over-func iterators), with go.mod declaring only tidwall/match v1.1.1 and tidwall/pretty v1.2.0 as external dependencies; everything else comes from the standard library (strconv, strings, time, unicode/utf16, unicode/utf8, unsafe). There’s no build tooling beyond go build/go test, and CI is a single GitHub Actions workflow that builds and tests on every push and PR to master. It’s distributed purely as an importable module, not a CLI (the companion jj command-line tool lives in a separate repository).

Code Quality

gjson_test.go contains 99 test functions and 3 benchmarks using only the standard testing package, covering path syntax edge cases, modifiers, JSON Lines, and the byte-level zero-copy behavior of GetBytes. Error handling is mostly implicit: malformed JSON doesn’t panic but silently returns zero-value Results rather than an error, and accessor methods favor forgiving empty-value fallbacks over strict validation, a deliberate ergonomics tradeoff for a no-error-checking query API. The GetBytes fast path uses unsafe.Pointer casts to avoid copying between string and []byte, a documented and contained optimization. Naming is consistent across the parseX/validX function families; CI runs build and test but no linter step is configured.

What Makes It Unique

The dot-notation path syntax supports inline array queries (#(age>45), #(last=="Murphy")#), wildcards, and pipe-chained modifiers (@reverse, @flatten, @group, @dig, and more), letting callers extract or reshape deeply nested values in a single expression instead of unmarshaling into a struct or writing manual type assertions. The zero-copy GetBytes path and per-match Index/Indexes tracking (for locating a matched value back in the original source text) are low-level techniques not commonly found together in comparable Go JSON libraries.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers