Skip to main content

toon-py

Token-Oriented Object Notation (TOON) for Python

A compact, human-readable format for passing structured data to LLMs with 30-60% fewer tokens than JSON.

Python port of @byjohann/toon.

Why TOON?

LLM tokens cost money. TOON reduces token usage by:

  • Removing redundant punctuation (braces, brackets, most quotes)
  • Using indentation for structure
  • Tabularizing arrays of objects
  • Writing inline primitive arrays without spaces

Installation

As a CLI tool

For standalone CLI usage:

# Using uv (recommended - installs in isolated environment)
uv tool install toon-py

# Using pip (installs CLI in current Python environment)
pip install toon-py

As a Python library

To use in your Python project:

# Using uv (adds to project dependencies)
uv add toon-py

# Using pip (installs library + CLI in current environment)
pip install toon-py

Quick Start

Python API

from toon_py import encode

data = {
    "user": {
        "id": 123,
        "name": "Ada",
        "tags": ["reading", "gaming"],
        "active": True
    }
}

print(encode(data))

Output:

user:
  id: 123
  name: Ada
  tags[2]: reading,gaming
  active: true

CLI

# From file
toon data.json

# From stdin
cat data.json | toon

# From string
toon '{"tags": ["foo", "bar"]}'

# With options
toon data.json --delimiter tab --length-marker -o output.toon

Token Savings

Example JSON Tokens TOON Tokens Saved Reduction
Simple user 31 18 13 41.9%
User with tags 48 28 20 41.7%
Product catalog 117 49 68 58.1%
API response 123 53 70 56.9%
Analytics data 209 94 115 55.0%
Large dataset (50 records) 2159 762 1397 64.7%

Features

Objects

encode({"id": 1, "name": "Ada"})
id: 1
name: Ada

Primitive Arrays (Inline)

encode({"tags": ["admin", "ops", "dev"]})
tags[3]: admin,ops,dev

Arrays of Objects (Tabular)

encode({
    "items": [
        {"sku": "A1", "qty": 2, "price": 9.99},
        {"sku": "B2", "qty": 1, "price": 14.5}
    ]
})
items[2]{sku,qty,price}:
  A1,2,9.99
  B2,1,14.5

Encoding Options

from toon_py import encode, EncodeOptions

data = {"items": [{"id": 1, "name": "Widget"}]}

# Tab delimiter
options = EncodeOptions(delimiter="\t")
print(encode(data, options))

# Pipe delimiter
options = EncodeOptions(delimiter="|")
print(encode(data, options))

# Length marker
options = EncodeOptions(length_marker="#")
print(encode(data, options))
# Output: items[#1]{id,name}: ...

# Custom indent
options = EncodeOptions(indent=4)
print(encode(data, options))

CLI Options

toon [INPUT] [OPTIONS]

Arguments:
  INPUT                 JSON file, JSON string, or stdin

Options:
  -i, --indent INT      Spaces per indent level (default: 2)
  -d, --delimiter TEXT  Delimiter: comma, tab, or pipe (default: comma)
  -l, --length-marker   Add '#' prefix to array lengths
  -o, --output PATH     Output file (default: stdout)
  --help                Show help message

Format Rules

Quoting

Keys and values are quoted only when necessary:

# Unquoted
{"name": "hello world"}  # -> name: hello world

# Quoted (contains comma)
{"note": "hello, world"}  # -> note: "hello, world"

# Quoted (looks like number)
{"code": "123"}  # -> code: "123"

# Quoted (key with space)
{"full name": "Ada"}  # -> "full name": Ada

Tabular Format

Arrays of objects use tabular format when:

  • All elements are objects
  • All objects have identical keys
  • All values are primitives (no nested arrays/objects)
encode({
    "users": [
        {"id": 1, "name": "Alice", "active": True},
        {"id": 2, "name": "Bob", "active": False}
    ]
})
users[2]{id,name,active}:
  1,Alice,true
  2,Bob,false

Empty Containers

encode({})            # -> (empty output)
encode({"items": []}) # -> items[0]:
encode({"config": {}})# -> config:

Type Conversions

Python Type TOON Output
None null
True/False true/false
123 123
-0.0 0
float('nan') null
float('inf') null
datetime(...) "2025-01-01T00:00:00Z"

Use in LLM Prompts

Wrap TOON data in code blocks:

Here's the data in TOON format:

```
user:
  id: 123
  tags[2]: reading,gaming
  active: true
```

Please analyze this data...

Development

# Clone and setup
git clone https://github.com/shammianand/toon-py.git
cd toon-py
uv sync --all-extras

# Run tests
uv run pytest

# Format code
uv run black src/
uv run ruff check src/

License

MIT License - see LICENSE

Credits

Python port of @byjohann/toon by Johann Schopplich

Metadata

Release files for toon-py 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toon-py 1.0.2
File Size Uploaded Provenance
toon_py-1.0.2.tar.gz 23.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for toon-py 1.0.2
File Interpreter ABI Platform
toon_py-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 31.9 kB

Release files / toon_py-1.0.2.tar.gz

Download URL toon_py-1.0.2.tar.gz
Size 23.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b802d947b3aef3f7c7a5f328f99da1da154b872b12e5022826864a7d25f5e2b1
BLAKE2b-256 checksum
How to use checksums
80e9ae863d706c261a9a4fdb64b3ed5824435903f63a0318598d4f5d54036266
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.5

Release files / toon_py-1.0.2-py3-none-any.whl

Download URL toon_py-1.0.2-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1fc8341389c4a1b00502e0d07f65887d19f7c102687e80e9eb191a4eb9496ec
BLAKE2b-256 checksum
How to use checksums
cdc92042883f474d076fab3a7d6fde255e598c03036fe3e75d9c0fcdc31205bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.5

Security for toon-py 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page