This project outlines the differences, improvements, and new features between Go's standard encoding/json package and the experimental encoding/json/v2 package.
| File | Purpose |
|---|---|
| 1_json_issues_test.go | Common encoding/json issues: UTF-8 validation, duplicate keys, nil marshaling, case-sensitivity |
| 2_json_options_test.go | New json/v2 options: StringifyNumbers, Deterministic, FormatNil*, OmitZero, RejectUnknown |
| 3_json_tag_options_test.go | Struct tags: case:ignore, string, omitempty, omitzero, unknown, inline, format tags |
| 4_marshallers_test.go | Custom marshaling with MarshalFunc (example: musical notation → Unicode symbols) |
| 5_json_streaming_benchmark_test.go | Performance comparison: v1 Encoder vs v2 MarshalWrite streaming |
- Go 1.25+ (for experimental json/v2 support)
- Experimental
encoding/json/v2package
# Set environment variable globally
export GOEXPERIMENT=jsonv2
# Or prefix commands
GOEXPERIMENT=jsonv2 go test ./...go mod tidy# All tests
go test -v ./...
# Specific test
go test -v -run TestUnmarshalInvalidUTF8$
# Specific file
go test -v ./1_json_issues_test.go
# Pattern matching
go test -v -run "TestUnmarshal.*"# All benchmarks
go test -bench=. -benchmem
# Streaming benchmarks
go test -bench=BenchmarkStreaming -benchmem ./5_json_streaming_benchmark_test.go✅ Better UTF-8 validation - RFC 8259 compliant, rejects invalid UTF-8
✅ Duplicate key detection - Defaults to rejecting duplicate object keys
✅ Improved nil handling - Marshals nil slices/maps as []/{} instead of null
✅ Case-sensitive by default - Use case:ignore tag for case-insensitive matching
✅ Rich marshal/unmarshal options - StringifyNumbers, Deterministic, OmitZero, etc.
✅ Format tags - Built-in formatting for time.Time, []byte, net.IP (hex, base64, RFC3339)
✅ Type-safe custom marshalers - MarshalFunc without interface implementation
✅ Low-level API - Token-based parsing with jsontext package
| Feature | encoding/json (v1) | encoding/json/v2 |
|---|---|---|
| Invalid UTF-8 | Accepts | Rejects (error) |
| Duplicate keys | Last value wins | Rejects (error) |
| Nil slices/maps | null |
[] / {} |
| Field matching | Case-insensitive | Case-sensitive (opt-in insensitive) |
| Custom marshaling | Interface methods | MarshalFunc |