toon-format/toon-go

🐹 Community-driven Go implementation of TOON

Go

148

21 commits

updated Oct 9, 2026

See the code

README

TOON for Go

Go Reference SPEC v4.4 License: MIT

Encodes Go values to TOON (Token-Oriented Object Notation) and decodes TOON back. TOON is a compact, indentation-based encoding of the JSON data model for LLM input.

Installation

go get github.com/toon-format/toon-go

Usage

package main

import (
	"fmt"

	"github.com/toon-format/toon-go"
)

type User struct {
	ID   int    `toon:"id"`
	Name string `toon:"name"`
	Role string `toon:"role"`
}

type Payload struct {
	Users []User `toon:"users"`
}

func main() {
	in := Payload{Users: []User{{1, "Ada", "admin"}, {2, "Bob", "user"}}}

	encoded, err := toon.MarshalString(in)
	if err != nil {
		panic(err)
	}
	fmt.Println(encoded)
	// users[2]{id,name,role}:
	//   1,Ada,admin
	//   2,Bob,user

	var out Payload
	if err := toon.UnmarshalString(encoded, &out); err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", out)
	// {Users:[{ID:1 Name:Ada Role:admin} {ID:2 Name:Bob Role:user}]}
}

Without a destination type, Decode and DecodeString return map[string]any, []any, and primitives. Pass encoder options to Marshal and decoder options to Unmarshal or Decode:

OptionDefaultDescription
WithIndent(n)2Spaces per indentation level when encoding
WithDelimiter(d)DelimiterCommaDelimiter for array values and tabular rows: DelimiterComma, DelimiterTab, or DelimiterPipe
WithTimeFormatter(f)RFC 3339 in UTCFormats time.Time values
WithStrictMode(b)truefalse accepts declared counts that don't match, duplicate keys (the last wins), tab or misaligned indentation, blank lines inside an array or keyed tabular object, and a block indented too deep; every other decoding error stays
WithDecoderIndent(n)2Expected spaces per indentation level when decoding

Specification

Targets TOON spec v4.4, and the test suite runs the spec's conformance fixtures.

  • Numbers decode to float64 – integers beyond 2^53 lose precision and a token that overflows float64 (e.g. 1e999) decodes as a string; on encode, integers beyond ±(2^53 − 1), *big.Int values included, become quoted decimal strings (§4)
  • Structs encode as objects keyed by their toon tags – toon:"name" renames, toon:"name,omitempty" skips zero values, toon:"-" skips the field, a field without a toon tag falls back to its json tag, and an untagged field uses its Go name; maps need string keys, time.Time and fmt.Stringer values become strings, and NaN and ±Inf become null (§3)
  • Decoded objects are map[string]any, so document key order is lost – on encode, toon.Object keeps its field order and Go maps are written in sorted key order (§2)

Releases follow SemVer: a new spec MINOR version ships as a MINOR release, even when it changes how hand-written input decodes, and a MAJOR release means an API break or a new spec MAJOR version.

Resources

  • Specification: SPEC.md – Normative rules and conformance checklists
  • Format Overview: toonformat.dev – Every form with examples
  • Other Implementations: toonformat.dev – TOON in other languages
  • API Reference: pkg.go.dev – Every exported function and option

Contributing

See CONTRIBUTING.md for the development setup and pull request guidelines.

License

MIT License © 2025-PRESENT Bintang Pradana Erlangga Putra and Johann Schopplich

golang
serialization
toon

toon-format/toon-go

🐹 Community-driven Go implementation of TOON

Go

148

21 commits

updated Oct 9, 2026

See the code

README

TOON for Go

Go Reference SPEC v4.4 License: MIT

Encodes Go values to TOON (Token-Oriented Object Notation) and decodes TOON back. TOON is a compact, indentation-based encoding of the JSON data model for LLM input.

Installation

go get github.com/toon-format/toon-go

Usage

package main

import (
	"fmt"

	"github.com/toon-format/toon-go"
)

type User struct {
	ID   int    `toon:"id"`
	Name string `toon:"name"`
	Role string `toon:"role"`
}

type Payload struct {
	Users []User `toon:"users"`
}

func main() {
	in := Payload{Users: []User{{1, "Ada", "admin"}, {2, "Bob", "user"}}}

	encoded, err := toon.MarshalString(in)
	if err != nil {
		panic(err)
	}
	fmt.Println(encoded)
	// users[2]{id,name,role}:
	//   1,Ada,admin
	//   2,Bob,user

	var out Payload
	if err := toon.UnmarshalString(encoded, &out); err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", out)
	// {Users:[{ID:1 Name:Ada Role:admin} {ID:2 Name:Bob Role:user}]}
}

Without a destination type, Decode and DecodeString return map[string]any, []any, and primitives. Pass encoder options to Marshal and decoder options to Unmarshal or Decode:

OptionDefaultDescription
WithIndent(n)2Spaces per indentation level when encoding
WithDelimiter(d)DelimiterCommaDelimiter for array values and tabular rows: DelimiterComma, DelimiterTab, or DelimiterPipe
WithTimeFormatter(f)RFC 3339 in UTCFormats time.Time values
WithStrictMode(b)truefalse accepts declared counts that don't match, duplicate keys (the last wins), tab or misaligned indentation, blank lines inside an array or keyed tabular object, and a block indented too deep; every other decoding error stays
WithDecoderIndent(n)2Expected spaces per indentation level when decoding

Specification

Targets TOON spec v4.4, and the test suite runs the spec's conformance fixtures.

  • Numbers decode to float64 – integers beyond 2^53 lose precision and a token that overflows float64 (e.g. 1e999) decodes as a string; on encode, integers beyond ±(2^53 − 1), *big.Int values included, become quoted decimal strings (§4)
  • Structs encode as objects keyed by their toon tags – toon:"name" renames, toon:"name,omitempty" skips zero values, toon:"-" skips the field, a field without a toon tag falls back to its json tag, and an untagged field uses its Go name; maps need string keys, time.Time and fmt.Stringer values become strings, and NaN and ±Inf become null (§3)
  • Decoded objects are map[string]any, so document key order is lost – on encode, toon.Object keeps its field order and Go maps are written in sorted key order (§2)

Releases follow SemVer: a new spec MINOR version ships as a MINOR release, even when it changes how hand-written input decodes, and a MAJOR release means an API break or a new spec MAJOR version.

Resources

  • Specification: SPEC.md – Normative rules and conformance checklists
  • Format Overview: toonformat.dev – Every form with examples
  • Other Implementations: toonformat.dev – TOON in other languages
  • API Reference: pkg.go.dev – Every exported function and option

Contributing

See CONTRIBUTING.md for the development setup and pull request guidelines.

License

MIT License © 2025-PRESENT Bintang Pradana Erlangga Putra and Johann Schopplich

golang
serialization
toon

Project health

Latest release

v1.0.1 · Oct 9, 2026

Releases this year

4

Significant stargazers

Christophe Colombier

214 followers · starred Nov 2025

Matthias Loibl

541 followers · starred Mar 2026

Jürgen Keck

29 followers · starred Nov 2025

Alby Hernández

188 followers · starred Mar 2026