Thanks to visit codestin.com
Credit goes to github.com

Skip to content
/ toon Public

πŸŽ’ Token-Oriented Object Notation – JSON for LLMs at half the token cost

License

Notifications You must be signed in to change notification settings

rumpl/toon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TOON - Token-Oriented Object Notation for Go

Original TOON (TypeScript/JavaScript) - The original implementation

A Go implementation of Token-Oriented Object Notation (TOON) - a compact, human-readable format designed for passing structured data to Large Language Models with significantly reduced token usage.

TOON saves ~50-60% of tokens compared to standard JSON while remaining readable and parseable by LLMs. It's perfect for:

  • πŸ’° Reducing LLM API costs
  • πŸ“Š Passing large datasets to LLMs
  • πŸš€ Optimizing context window usage
  • πŸ€– Structured data in AI applications

Installation

go get github.com/rumpl/toon

Quick Start

package main

import (
    "fmt"
    "github.com/rumpl/toon"
)

func main() {
    data := map[string]any{
        "users": []any{
            map[string]any{"id": 1, "name": "Alice", "role": "admin"},
            map[string]any{"id": 2, "name": "Bob", "role": "user"},
        },
        "total": 2,
    }

    result, _ := toon.Encode(data)
    fmt.Println(result)
}

Output:

total: 2
users[2]{id,name,role}:
  1,Alice,admin
  2,Bob,user

Compare this to the equivalent JSON (123 tokens vs 53 TOON tokens = 57% reduction):

{
  "users": [
    { "id": 1, "name": "Alice", "role": "admin" },
    { "id": 2, "name": "Bob", "role": "user" }
  ],
  "total": 2
}

Key Features

  • Token-efficient: 50-65% fewer tokens than JSON
  • LLM-friendly: Explicit lengths and field lists help models validate output
  • Minimal syntax: Removes redundant punctuation
  • Indentation-based: Clean, readable structure
  • Tabular arrays: Efficient format for uniform data
  • Struct support: Works with Go structs using json tags
  • Customizable: Support for different delimiters (comma, tab, pipe)

Format Overview

Objects

data := map[string]any{
    "id": 123,
    "name": "Ada",
    "active": true,
}
toon.Encode(data)
// id: 123
// name: Ada
// active: true

Nested Objects

data := map[string]any{
    "user": map[string]any{
        "id": 123,
        "name": "Ada",
    },
}
toon.Encode(data)
// user:
//   id: 123
//   name: Ada

Arrays of Primitives

data := map[string]any{
    "tags": []string{"reading", "gaming", "coding"},
}
toon.Encode(data)
// tags[3]: reading,gaming,coding

Arrays of Objects (Tabular)

When all objects share the same primitive fields, TOON uses an efficient tabular format:

items := []any{
    map[string]any{"sku": "A1", "qty": 2, "price": 9.99},
    map[string]any{"sku": "B2", "qty": 1, "price": 14.5},
}
data := map[string]any{"items": items}
toon.Encode(data)
// items[2]{price,qty,sku}:
//   9.99,2,A1
//   14.5,1,B2

Struct Support

TOON works seamlessly with Go structs:

type User struct {
    ID     int    `json:"id"`
    Name   string `json:"name"`
    Active bool   `json:"active"`
}

user := User{ID: 123, Name: "Ada", Active: true}
result, _ := toon.Encode(user)
// active: true
// id: 123
// name: Ada

Root-Level Arrays

data := []any{"x", "y", "z"}
toon.Encode(data)
// [3]: x,y,z

Advanced Options

Custom Delimiters

Use tab or pipe delimiters for additional token savings:

opts := toon.EncodeOptions{
    Delimiter: toon.TabDelimiter,
}
result, _ := toon.EncodeWithOptions(data, opts)
// items[2	]{name	price}:
//   Widget	9.99
//   Gadget	14.50
opts := toon.EncodeOptions{
    Delimiter: toon.PipeDelimiter,
}
result, _ := toon.EncodeWithOptions(data, opts)
// items[2|]{name|price}:
//   Widget|9.99
//   Gadget|14.50

Length Markers

Add a # prefix to array lengths for clarity:

opts := toon.EncodeOptions{
    LengthMarker: true,
}
result, _ := toon.EncodeWithOptions(data, opts)
// tags[#3]: reading,gaming,coding

Custom Indentation

opts := toon.EncodeOptions{
    Indent: 4,
}
result, _ := toon.EncodeWithOptions(data, opts)
// user:
//     id: 123
//     name: Ada

Encoding Options

type EncodeOptions struct {
    // Indent is the number of spaces per indentation level (default: 2)
    Indent int

    // Delimiter is the delimiter for array values and tabular rows
    // Options: CommaDelimiter (default), TabDelimiter, PipeDelimiter
    Delimiter Delimiter

    // LengthMarker adds a # prefix to array lengths (default: false)
    LengthMarker bool
}

Type Conversions

TOON automatically handles various Go types:

Go Type TOON Output
int, float64 Numbers without quotes
string Quoted if needed (special chars, looks like number/bool)
bool true or false
nil null
time.Time ISO 8601 string
*big.Int Decimal digits (unquoted)
NaN, Β±Infinity null
-0 0

Quoting Rules

TOON quotes strings only when necessary:

Strings that need quoting:

  • Empty strings: ""
  • Contains delimiter, colon, or quotes: "a,b", "a:b"
  • Leading/trailing spaces: " padded "
  • Looks like boolean/number: "true", "42"
  • Contains control characters: "line1\nline2"

Strings safe unquoted:

  • Simple text: hello
  • Unicode & emoji: cafΓ©, πŸš€
  • Inner spaces: hello world

API Reference

Encode(value any) (string, error)

Encodes a value using default options (2-space indent, comma delimiter, no length marker).

result, err := toon.Encode(data)

EncodeWithOptions(value any, opts EncodeOptions) (string, error)

Encodes a value with custom options.

result, err := toon.EncodeWithOptions(data, toon.EncodeOptions{
    Indent:       4,
    Delimiter:    toon.TabDelimiter,
    LengthMarker: true,
})

Use Cases

1. Sending Data to LLMs

analytics := []any{
    map[string]any{"date": "2025-01-01", "views": 1234, "clicks": 89},
    map[string]any{"date": "2025-01-02", "views": 2345, "clicks": 156},
    map[string]any{"date": "2025-01-03", "views": 1890, "clicks": 123},
}

toonData, _ := toon.Encode(map[string]any{"metrics": analytics})

prompt := fmt.Sprintf(`Analyze this website data:
%s

What trends do you see?`, toonData)

// Send to LLM - uses ~55% fewer tokens than JSON!

2. Structured Logging

logEntry := map[string]any{
    "timestamp": time.Now(),
    "level": "ERROR",
    "service": "api",
    "error": map[string]any{
        "code": 500,
        "message": "Database connection failed",
    },
}

toonLog, _ := toon.Encode(logEntry)
fmt.Println(toonLog)

3. Configuration Export

config := AppConfig{
    Database: DBConfig{Host: "localhost", Port: 5432},
    Cache:    CacheConfig{TTL: 3600, MaxSize: 1000},
}

toonConfig, _ := toon.Encode(config)
// Compact, readable configuration format

Testing

Run the test suite:

go test -v

Run benchmarks:

go test -bench=. -benchmem

Token Savings Examples

Example JSON Tokens TOON Tokens Savings
Small product catalog 117 49 58.1%
API response with users 123 53 56.9%
Analytics data 209 94 55.0%
Large dataset (50 records) 2159 762 64.7%

Token counts measured with GPT-4 tokenizer (o200k_base)

Comparison with JSON

JSON (verbose):

{
  "items": [
    { "sku": "A1", "name": "Widget", "qty": 2, "price": 9.99 },
    { "sku": "B2", "name": "Gadget", "qty": 1, "price": 14.5 }
  ]
}

TOON (compact):

items[2]{name,price,qty,sku}:
  Widget,9.99,2,A1
  Gadget,14.5,1,B2

Credits

This is a Go implementation of the TOON specification created by Johann Schopplich.

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

About

πŸŽ’ Token-Oriented Object Notation – JSON for LLMs at half the token cost

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages