| Name | Modified | Size | Downloads / 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/jsondoes, including Go 1.27, whoseencoding/jsonis built onencoding/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 asencoding/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, ofencoding/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 ofreflect, so it builds with the restrictions of newer Go versions ongo:linkname.
New APIs
MarshalOf[T]: encodes a value of typeTwithout copying it to the heap ( [#632] ).UnmarshalOf[T]: decodes into a*Twhich 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/jsonof 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/jsondoes ( [#666] ). MarshalNoEscapeandUnmarshalNoEscapeare deprecated: useMarshalandUnmarshalOf( [#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