Download Latest Version v0.12.0 source code.zip (1.6 MB) Google Add to Preferred Sources
Home / v0.11.0
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-09-27 7.3 kB
v0.11.0 source code.tar.gz 2026-09-27 668.4 kB
v0.11.0 source code.zip 2026-09-27 784.9 kB
Totals: 3 Items   1.5 MB 0

Highlights

  • Compatible with encoding/json of the Go version in use: values are decoded and encoded, and errors are reported (their types, messages and offsets), as encoding/json does, including Go 1.27, whose encoding/json is built on encoding/json/v2. Many reported compatibility issues are fixed.
  • Much faster: with the same behavior as encoding/json ( a live heap of 64 MB, geometric mean over the payloads of the report ), go-json decodes about 4.2–4.4x and encodes about 2.7–2.8x as fast as encoding/json, on amd64 and arm64 ( the results of this release are at https://goccy.github.io/go-json/ ).
  • A benchmark report of the JSON libraries of Go, measured on GitHub Actions for every change and published at https://goccy.github.io/go-json/: the libraries are compared by category of behavior ( the behavior of encoding/json, of encoding/json/v2, without HTML escaping, key sorting and string copying, and every library at its fastest ), which every run checks, and the result files are attested with GitHub Artifact Attestations.
  • No more go:linkname: go-json no longer links to the internals of the runtime or of reflect, so it builds with the restrictions of newer Go versions on go:linkname.

New APIs

  • MarshalOf[T]: encodes a value of type T without copying it to the heap ( [#632] ).
  • UnmarshalOf[T]: decodes into a *T which may stay on the stack of the caller, without an allocation for the argument ( [#658] ).
  • OptimizeFieldOrder(): lets the encoder order the fields of a struct as it encodes them fastest, when the order of the keys doesn't matter ( [#646] ).
  • DecodeNoCopyString(): lets the decoded strings refer to the input instead of copying them ( [#658] ).

Changes of behavior

These follow encoding/json, and may change what a program which relied on the previous behavior gets:

  • The values of the keys which match no field are validated: invalid JSON anywhere in the input is a syntax error, as with encoding/json ( [#664] ).
  • Syntax errors and type errors are reported as encoding/json of the Go version reports them: their types, messages and offsets ( [#661], [#664] ).
  • A decoded string is a copy of its bytes, and doesn't keep the input alive; short strings share buffers of up to 16 KB ( [#658] ). Use DecodeNoCopyString() to refer to the input instead.
  • The elements of an array are decoded into the existing elements of a slice, including the ones after its length within its capacity, as encoding/json does ( [#666] ).
  • MarshalNoEscape and UnmarshalNoEscape are deprecated: use Marshal and UnmarshalOf ( [#631], [#658] ).
  • DecodeFieldPriorityFirstWin() no longer allocates for each object, and is as fast as the default decode or faster ( [#668] ).

What's Changed

Decoder

  • Decoder: decode a stream by the byte slice decoders, compare the decoder with sonic by @goccy in [#656]
  • Decoder: allocate and assign through reflect instead of go:linkname by @goccy in [#657]
  • Decoder: UnmarshalOf, copies of the decoded strings, recent decoders of a context by @goccy in [#658]
  • Decoder and encoder: struct keys by a table, numbers in one pass, strings by AVX2, benchmarks of real APIs by @goccy in [#659]
  • Decoder: allocate the value of a pointer by new of its kind by @goccy in [#660]
  • Decoder: report the type errors as encoding/json of the Go version does by @goccy in [#661]
  • Decoder: decode a value of interface{} without reflect by @goccy in [#662]
  • Decoder: decode the values held by interface values by their type, as encoding/json does by @goccy in [#663]
  • Decoder: fix the reported decoder issues, as encoding/json of the Go version decodes by @goccy in [#664]
  • Decoder: narrow the gaps to sonic on escaped strings, and compare with sonic as a real program runs by @goccy in [#665]
  • Decoder: narrow the gaps to sonic at its fastest: slices, maps, long escaped strings and interface values by @goccy in [#666]
  • Decoder: remember the decoded fields of DecodeFieldPriorityFirstWin in a bit set by @goccy in [#668]
  • Decoder: narrow the gap to sonic on interface{} values and string fields by @goccy in [#670]

Encoder

  • Remove go:linkname to reflect.(*rtype) methods by @goccy in [#624]
  • Remove runtime.Type and go:linkname to reflect.ifaceIndir by @goccy in [#625]
  • Always give the address of the value to the encoder VM by @goccy in [#626]
  • Fix the encoding of recursive structs and omitempty with a pointer receiver marshaler by @goccy in [#628]
  • Fix the indent of deep recursive structs, marshalers of empty values and embedded structs by @goccy in [#630]
  • Carry the values of the encoder VM as unsafe.Pointer and remove KeepRefs by @goccy in [#631]
  • Add MarshalOf, which encodes a value without copying it to the heap by @goccy in [#632]
  • Speed up the encoder: a hash table for the cache of a type, a lighter VM and a faster AppendString by @goccy in [#634]
  • Encode a scalar held by an interface value without a frame by @goccy in [#635]
  • Scan a string for a byte to escape by SIMD by @goccy in [#637]
  • Call the method of a marshaler directly by its code by @goccy in [#638]
  • Copy the output of a marshaler as it is if it is compact and valid by @goccy in [#639]
  • Encoder: inline the helpers of the VM, and shorter paths for strings and maps by @goccy in [#640]
  • Write the key of a map of strings by the opcode of the map entry by @goccy in [#641]
  • Encoder: encode fields of the same kind in a row without a dispatch between them by @goccy in [#643]
  • Encode a list of values of a recursive type in one frame by @goccy in [#645]
  • Add the option to let the encoder order the fields of a struct by @goccy in [#646]
  • Read the entries of a map without a linkname of the runtime by @goccy in [#647]
  • Encoder: compare the keys of a map by their first bytes as a number first by @goccy in [#649]
  • Encoder: cheaper frames of interface values by @goccy in [#650]
  • Encoder: write the scalar entries of an unordered map of interface values as the map is read by @goccy in [#651]
  • Write null for an interface value which holds nothing without a call by @goccy in [#652]
  • Encoder: encode a field of interface{} by an opcode of its own by @goccy in [#653]
  • Test the cases of the reported issues of the encoder by @goccy in [#655]

Other fixes

  • Fix encode/decoder compile data race by @TelpeNight in [#567]

Benchmarks, documents and CI

  • Fix CI failures on master caused by outdated Go versions by @goccy in [#594]
  • Add bench-check task to fail CI on performance degradation by @goccy in [#623]
  • Judge the benchmarks by the mean and by the fastest results by @goccy in [#629]
  • Benchmarks: add the benchmarks of sonic's encoder, with go-json beside it by @goccy in [#648]
  • Modernize the code: any, unsafe.Add, slices.Contains, min, max, bytes.Cut by @goccy in [#654]
  • Publish a benchmark report of the JSON libraries by category of behavior, describe the decoder as it is now in the README, and run no CI for documents alone by @goccy in [#667]
  • Benchmarks: color the bars of the summary by library by @goccy in [#669]

New Contributors

  • @TelpeNight made their first contribution in [#567]

Full Changelog: https://github.com/goccy/go-json/compare/v0.10.6...v0.11.0

Source: README.md, updated 2026-09-27