go-json
A fast, drop-in replacement for Go's encoding/json that skips reflection in favor of compiled opcode execution.
Repository Health
Technical Analysis
go-json is a JSON encoder/decoder for Go built to be a fully compatible, drop-in replacement for the standard library’s encoding/json — you swap a single import path and keep every existing struct tag, Marshaler, and Unmarshaler working exactly as before. Rather than walking values with reflect at encode/decode time, go-json compiles each type into a cached sequence of opcodes keyed by the type’s runtime address, then executes that opcode program directly against unsafe.Pointer offsets, cutting out the repeated reflection overhead that dominates encoding/json’s cost on hot paths.
Beyond raw throughput, go-json adds practical extras the standard library doesn’t offer: colorized/pretty debug output, context.Context propagation into custom MarshalJSON/UnmarshalJSON implementations, a JSONPath-style query API (CreatePath) for extracting values without decoding a whole document, and type-safe field filtering via FieldQuery so callers can trim struct output without hand-rolling a second type. It also exposes streaming encode/decode and an UnorderedMap option for callers who don’t need Go’s default sorted-map-key behavior.
The project has been maintained since 2020, has shipped 78 tagged releases, and is exercised by a large internal test suite (encode_test.go and decode_test.go alone cover tens of thousands of lines) plus CI running across Linux, macOS, and Windows, three Go versions, and the race detector on every push.
What You Get
- A drop-in replacement for encoding/json — change the import path, keep all existing json struct tags, Marshaler/Unmarshaler implementations, and Encoder/Decoder call sites
- Opcode-compiled encoding and decoding that avoids repeated reflect calls by caching a per-type instruction sequence keyed on the type’s runtime address
- context.Context propagation into MarshalJSON/UnmarshalJSON via MarshalContext/UnmarshalContext for request-scoped marshaling logic
- A CreatePath JSONPath-style query API to pull specific values out of a JSON document without decoding the whole structure
- Type-safe FieldQuery/BuildFieldQuery API to dynamically include only selected struct fields in output, avoiding a second stripped-down type
- Colorized and indented debug output via the Debug/Color encode options for readable terminal inspection during development
Common Use Cases
- Swapping encoding/json for go-json in high-throughput HTTP APIs or RPC services where JSON (de)serialization shows up in CPU profiles
- Services that pass context.Context through custom marshaling logic (e.g. request-scoped tracing or auth checks fired from MarshalJSON)
- Extracting a handful of fields from large JSON payloads via CreatePath instead of decoding and discarding most of the document
- Trimming API response fields per-caller at encode time with FieldQuery instead of maintaining parallel DTO structs
- Debugging JSON encoding issues locally with colorized/indented output instead of piping through a separate formatter
Under The Hood
Architecture go-json’s encode/decode paths (encode.go, decode.go, json.go) sit on top of two internal packages, internal/encoder and internal/decoder, which each implement a compiler (compiler.go) that turns a Go type into an OpcodeSet keyed by the type’s runtime pointer address and cached in a lock-free array (cachedOpcodeSets, an []atomic.Pointer[OpcodeSet]) rather than re-deriving it via reflection on every call; internal/runtime supplies the type-address bookkeeping this cache depends on, and separate vm/vm_color/vm_indent/vm_color_indent packages execute the same opcode program with different output formatting so the hot compiled path doesn’t fork per output mode. Top-level API (Marshal/Unmarshal, Encoder/Decoder, CreatePath, FieldQuery) is a thin public wrapper that acquires a pooled RuntimeContext, sets option flags (HTML escaping, UTF-8 normalization, context propagation), and delegates into these compiled paths, so the abstraction that would break the most if changed is the OpcodeSet/type-address cache — nearly everything else is built on top of it.
Tech Stack Written in pure Go (module targets go 1.19, tested through 1.21) with zero runtime dependencies outside the standard library — it deliberately reimplements pieces of encoding/json and reflect-adjacent primitives itself (internal/runtime) rather than depending on external reflection helpers. It uses unsafe.Pointer and sync/atomic directly for the type-address cache and buffer reuse instead of a general-purpose caching library, and ships a Dockerfile/docker-compose.yml so its “build on limited environment” CI job can run in a constrained container rather than the full GitHub Actions runner.
Code Quality
The repo carries an unusually large test suite relative to its size — encode_test.go and decode_test.go together are tens of thousands of lines, covering type combinations exhaustively, alongside dedicated color_test.go, path_test.go, query_test.go, stream_test.go, and tagkey_test.go files. CI (.github/workflows) runs the full suite on ubuntu/macos/windows across three Go versions, once normally, once under artificial GC pressure (GOGC=1), and once with the race detector, then runs a separate golangci-lint job configured with enable-all linters (with a short, deliberate disable list). Error handling is explicit and typed (internal/errors package) rather than swallowed, and public option/query APIs are validated at call time rather than trusting caller input silently.
What Makes It Unique Most faster JSON libraries for Go (easyjson, gojay, ffjson) trade encoding/json compatibility for speed by requiring code generation or a different API; go-json’s distinguishing choice is keeping full drop-in compatibility (same interfaces, same struct tags, same Marshaler/Unmarshaler contracts) while still avoiding reflection at runtime, by compiling per-type opcode programs once and caching them by type address instead of by generated source file. Its JSONPath query support and type-safe field-filtering query system are also not offered by encoding/json or most of its faster competitors, giving it selective-read and selective-write capabilities on top of the performance work.
Used by 4 apps in this directory
Apache Answer
Community
Open-source Q&A platform for communities, help centers, and knowledge bases with AI assistant and plugin extensibility
Dolt
Databases · Data Engineering · Developer Tools
The SQL database you can branch, merge, diff, and clone — Git for your data, MySQL-compatible and ready for multi-agent AI workflows.
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.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.