JSON

A single, platform-agnostic JSON codec for Go that optimizes WebAssembly binary size by using zero reflection. It relies on fmt.Fielder for struct encoding/decoding, which is typically generated by ormc.
Index
Architecture
- Zero Reflection: Uses type switches and
fmt.Fielder instead of the reflect package.
- Platform-Agnostic: Identical behavior on all platforms (WASM, Linux, macOS, etc.).
- TinyGo Compatible: Optimized for minimal binary size and memory usage.
- Fielder-Only: Only types implementing
fmt.Fielder can be directly encoded or decoded.
Usage
Structs
Structs MUST implement fmt.Fielder to be supported. This is normally handled by generating code with ormc.
package main
import (
"github.com/tinywasm/fmt"
"github.com/tinywasm/json"
)
// User implements fmt.Fielder (typically via ormc)
type User struct {
Name string
}
func (u *User) Schema() []fmt.Field {
return []fmt.Field{{Name: "Name", Type: fmt.FieldText, JSON: "name"}}
}
func (u *User) Pointers() []any { return []any{&u.Name} }
func main() {
u := User{Name: "Alice"}
var out string
if err := json.Encode(&u, &out); err != nil {
panic(err)
}
// out: {"name":"Alice"}
var result User
if err := json.Decode(out, &result); err != nil {
panic(err)
}
}
API
Encode(data fmt.Fielder, output any) error
Serializes a Fielder to JSON.
- data: Must implement
fmt.Fielder.
- output:
*[]byte, *string, or io.Writer.
Parses JSON into a Fielder.
- input:
[]byte, string, or io.Reader.
- data: Must implement
fmt.Fielder.
Benchmarks
tinywasm/json is 77% smaller than encoding/json in WASM (~27 KB vs ~119 KB)
and zero-reflect, eliminating reflection overhead and heavy dependencies.
| Benchmark |
tinywasm/json |
encoding/json |
| Encode |
641 ns/op |
573 ns/op |
| Decode |
1709 ns/op |
2184 ns/op |
See full results and analysis in benchmarks/README.md.
Contributing
License
See LICENSE for details.