ojg

A high-performance JSON parser and toolkit for Go with a full JSONPath implementation.

Library
Go
vv1.28.5
955stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity76
Maintenance60
Community48
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture82
Code Quality85
Innovation78
Learning Curve65

OjG (Optimized JSON for Go) is a high-performance JSON toolkit built around a hand-written parser that outperforms Go’s standard encoding/json package, especially when reused across multiple parses via its buffer-reuse design. Beyond parsing, it ships a complete JSONPath implementation that operates on both plain Go values (maps, slices) and typed structs, along with a generic type system, a fast validator, a SEN (Simple Encoding Notation) format, and the oj CLI for filtering, reformatting, and colorizing JSON from the command line.

The library targets workloads where JSON doesn’t fit a fixed schema, such as log processing and ETL pipelines over large, irregular data sets, trading struct-tag-based unmarshalling for a faster parse-then-query workflow built on JSONPath.

What You Get

  • Buffer-reusing JSON parser (oj) that is measurably faster than encoding/json, especially on repeated parses
  • Full JSONPath implementation (jp) that queries plain Go values and tagged structs alike
  • Generic, type-safe JSON element types (gen) for cases where interface{} sprawl is a problem
  • SEN (Simple Encoding Notation), a comma/quote-free JSON dialect for hand-written config and logs
  • The oj command-line tool for filtering, sorting, reformatting, and colorizing JSON documents
  • Reflection-based decompose/recompose (alt) for converting between structs and simple types

Common Use Cases

  • Parsing huge irregular data sets - teams processing logs or ETL streams where records don’t conform to one fixed struct use ojg’s Parser with Reuse enabled to cut allocations across millions of parses
  • Querying nested JSON without a schema - developers extracting values from deeply nested, variably-shaped JSON reach for jp’s JSONPath expressions instead of writing custom map-walking code
  • CLI JSON wrangling - engineers use the oj binary to filter, sort, and pretty-print JSON files or streams during debugging or shell pipelines
  • Type-safe JSON construction - services building JSON payloads programmatically use the gen package’s typed Bool/Int/Float/String/Array/Object nodes to avoid interface{} bugs
  • Config files in SEN format - projects wanting a lighter-weight, quote-free JSON-like syntax for hand-authored config adopt SEN via the sen package

Under The Hood

Architecture ojg is organized as a set of loosely coupled packages (oj, jp, gen, alt, sen, discover, pretty, asm) that interoperate through a shared contract of simple Go types (bool, int64, float64, string, []any, map[string]any). oj.Parser (oj/parser.go) is a reusable struct that retains its internal byte buffers, container stack, and map pool across calls instead of relying on encoding/json, and jp implements JSONPath (jp/get.go) using an explicit pseudo-call stack rather than plain recursion, a deliberate trade made for speed. alt.Decompose/Recompose bridges the generic-type world back to arbitrary structs via reflection, so parsing, querying, and struct conversion are each independently testable layers sitting on one shared type contract. Because so many packages (jp, alt, gen, sen, pretty) key off that shared simple-type set, it functions as the load-bearing abstraction of the whole library — changing it would ripple through every package.

Tech Stack The module (github.com/ohler55/ojg, Go 1.18) declares zero third-party dependencies in go.mod, relying entirely on the Go standard library and its own hand-rolled tokenizer, writer, and validator instead of wrapping encoding/json. CI (go.yml) runs go build ./... and go test -v ./... on GitHub Actions against Go 1.19 for every push and pull request to the develop branch. The module distributes as a standard Go package (go get) plus a companion CLI (cmd/oj), installable via go install or Homebrew, with no web framework, ORM, or database dependency since the library’s entire surface is JSON processing.

Code Quality Test coverage is extensive and close to 1:1 with implementation files (142 _test.go files against roughly 230 non-test .go files), and nearly every package (oj, gen, sen, pretty, jp, alt, asm) ships a dedicated example_test.go that doubles as runnable GoDoc documentation. Error handling is explicit rather than swallowed: idiomatic errors.New/fmt.Errorf calls are used throughout for real error paths, while a smaller, deliberate set of panics is confined to Must* convenience wrappers (e.g. gen.Builder.MustObject calling the error-returning Object() and panicking only on its result) — a clear two-tier Try/Must API rather than silently ignored failures. A .golangci.yml is present for static analysis and the README tracks a Go Report Card badge.

What Makes It Unique Rather than wrapping encoding/json, ojg hand-writes its parser, tokenizer, writer, and validator with an explicit buffer-reuse mode (Parser.Reuse) that the project’s own benchmarks show cuts allocations roughly threefold over encoding/json on repeated parses, and it implements JSONPath with a non-recursive, stack-based evaluator specifically to avoid Go function-call overhead — a deliberate architectural choice against the more common recursive-descent approach. It also introduces SEN, a JSON-superset format that drops most quotes and commas for faster hand-editing and logging, a genuinely distinctive addition not found 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

Search