jsonparser
A fast, allocation-free JSON parser for Go that reads values by key path without unmarshaling into structs.
Repository Health
Technical Analysis
jsonparser is a Go library for extracting values from JSON payloads without knowing their full structure ahead of time or paying the cost of encoding/json’s reflection-based unmarshaling. Instead of decoding into a struct or a generic map[string]interface{}, it walks the raw byte slice and returns pointers to the requested keys directly, making it well suited to APIs with unpredictable or partially-relevant JSON responses.
The library has stayed dependency-free and API-stable for a decade while adding opt-in extensions: a Config type for lenient parsing (single-quoted strings, unknown escape sequences), a ReaderParser for streaming large documents from an io.Reader with a bounded sliding window, an EachKey batching API for extracting many paths in a single pass, and wildcard path support (EachKeyWildcard) for fanning out over arrays. It backs its performance and correctness claims with an unusually deep test suite spanning property-based tests, differential tests against encoding/json, native Go fuzzing, and a formal-verification/MC-DC audit pipeline.
What You Get
- Key-path value extraction (
Get,GetString,GetInt,GetFloat,GetBoolean) directly against a[]bytepayload, with array-index path segments like[0] - Zero-allocation string reads via
GetUnsafeStringfor callers willing to tie the returned string’s validity to the underlying buffer - Batched multi-path extraction with
EachKey, which scans the payload once and dispatches a callback per matched path instead of re-scanning per call ReaderParserfor streaming path-based lookups over anio.Readerwith a configurable sliding-window buffer, so large documents don’t need to be loaded into memory at once- Opt-in lenient parsing via
Config{AllowSingleQuotes, AllowUnknownEscapes}for JSON5-ish input, alongside the strict RFC 8259 default - In-place mutation helpers (
Set,Delete) and iteration helpers (EachArray,EachObject,EachKeyWildcard) for arrays and objects addressed by key path
Common Use Cases
- Extracting a handful of fields from large or unpredictable third-party API responses without maintaining a matching struct
- High-throughput services where
encoding/json’s reflection-based unmarshal cost is measurable, and only partial payload access is needed - Streaming large JSON documents from disk or network without buffering the entire payload in memory
- Reading loosely-formatted or hand-edited JSON-like config files that use single quotes or non-standard escapes
- Batch-extracting many known fields from the same payload in one pass via
EachKey, instead of repeatedGetcalls
Under The Hood
Architecture
The library is a single flat package built around a handful of core files rather than a layered or dependency-injected design, since it’s a leaf library with no framework responsibilities: parser.go holds the core token-scanning primitives (tokenEnd, findTokenStart, findKeyStart, internalGetConfig) that every higher-level function funnels through; config.go defines the Config struct and package-level Get/GetString/etc. as thin wrappers around a shared DefaultConfig instance, so the strict and lenient code paths stay unified; path_compiler.go translates JSONPath-style dotted strings into the ...string key-path arguments the rest of the API expects; wildcard.go builds array fan-out on top of the base Get/ArrayEach primitives rather than duplicating traversal logic; and reader_parser.go adds a streaming variant with its own sliding-window buffer that still calls into the same scanning helpers used by the byte-slice API. aliases.go keeps older names (ArrayEach, ObjectEach) as one-line forwarders to the canonical EachArray/EachObject. Because every public function depends on the same core offset-computation primitives, a change there has broad blast radius across the whole API surface — which the repo’s unusually heavy test and formal-verification layer is clearly built to guard against.
Tech Stack
Pure standard-library Go with zero third-party runtime dependencies — go.mod declares go 1.13 and an empty go.sum, using only bytes, encoding/binary, errors, fmt, io, strconv, and strings, plus isolated unsafe use for zero-copy string views. Build and test tooling is a plain Makefile wrapping go test/go vet/go fmt inside a Docker container; a separate benchmark/ module with its own go.mod pulls in comparison libraries (ffjson, easyjson, gjson, sonic) purely for benchmarking, kept out of the main module’s dependency graph. CI runs Google OSS-Fuzz builds on every PR (cifuzz.yml) and, more unusually for a library this size, a formal-verification/MC-DC audit (reqproof.yml) against requirement specs under specs/ using a Z3 SMT solver.
Code Quality
Test coverage is extensive relative to the library’s size — the majority of its Go files are test files, spanning ordinary table-driven tests, property-based tests, a differential suite comparing output against encoding/json, native Go fuzz targets, and dedicated regression tests pinned to specific historical issue numbers. Error handling is explicit and idiomatic: sentinel errors rather than panics, with callback-based iteration surfacing per-element parse errors through the callback signature instead of swallowing them. Naming is consistent (Get/GetString/GetInt/GetFloat/GetBoolean following one pattern, with older ArrayEach/ObjectEach names kept only as compatibility aliases). unsafe usage is isolated to two dedicated files behind a shared interface rather than scattered through the codebase, and go vet/go fmt are wired into the Makefile.
What Makes It Unique
The core differentiator is avoiding both reflection and pre-declared structs — Get/EachKey/EachArray locate values by key path directly against the raw byte slice, with GetUnsafeString offering zero-allocation string views for callers willing to tie memory validity to the underlying buffer. EachKey batches multiple path lookups into a single scan rather than re-scanning per call, and more recent additions extend the same key-path model to streaming io.Reader input via ReaderParser with a bounded sliding window, plus opt-in lenient parsing for single-quoted or loosely-escaped input. None of these ideas are unique in isolation — byte-slice JSON scanning, unsafe string views, and streaming parsers all exist in other libraries — but the specific combination of zero dependencies, one-pass multi-key extraction, and a formal-verification/property-test harness layered on top of ordinary Go testing is a distinguishing engineering choice.
Used by 4 apps in this directory
Coroot
Analytics · Monitoring
eBPF-powered observability with AI root cause analysis — zero code changes required, full-stack visibility out of the box.
MinIO
File Storage
High-performance, S3-compatible object storage built for AI/ML and analytics workloads — run it anywhere from a laptop to a petabyte-scale cluster.
Tyk API Gateway
Developer Tools · Devops
Cloud-native, high-performance open-source API gateway for REST, GraphQL, gRPC, and TCP — built in Go since 2014 with no feature lockout.
Weaviate
Databases · Search
Open-source vector database combining semantic search, hybrid queries, RAG, and image search in a single cloud-native system built for production scale.