Community-driven Python implementation of TOON
⚠️ Beta Status (v0.9.x): This library is in active development and working towards spec compliance. Beta published to PyPI. API may change before 1.0.0 release.
Compact, human-readable serialization format for LLM contexts with 30-60% token reduction vs JSON. Combines YAML-like indentation with CSV-like tabular arrays. Working towards full compatibility with the official TOON specification.
Key Features: Minimal syntax • Tabular arrays for uniform data • Array length validation • Python 3.8+ • Comprehensive test coverage.
# Beta published to PyPI - install from source:
git clone https://github.com/toon-format/toon-python.git
cd toon-python
uv sync
# Or install directly from GitHub:
pip install git+https://github.com/toon-format/toon-python.gitfrom toon_format import encode, decode
# Simple object
encode({"name": "Alice", "age": 30})
# name: Alice
# age: 30
# Tabular array (uniform objects)
encode([{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}])
# [2,]{id,name}:
# 1,Alice
# 2,Bob
# Decode back to Python
decode("items[2]: apple,banana")
# {'items': ['apple', 'banana']}# Auto-detect format by extension
toon input.json -o output.toon # Encode
toon data.toon -o output.json # Decode
echo '{"x": 1}' | toon - # Stdin/stdout
# Options
toon data.json --encode --delimiter "\t" --length-marker
toon data.toon --decode --no-strict --indent 4Options: -e/--encode -d/--decode -o/--output --delimiter --indent --length-marker --no-strict
encode(value, options=None) → strencode({"id": 123}, {"delimiter": "\t", "indent": 4, "lengthMarker": "#"})Options:
delimiter: "," (default), "\t", "|"indent: Spaces per level (default: 2)lengthMarker: "" (default) or "#" to prefix array lengthsdecode(input_str, options=None) → Anydecode("id: 123", {"indent": 2, "strict": True})Options:
indent: Expected indent size (default: 2)strict: Validate syntax, lengths, delimiters (default: True)Measure token efficiency and compare formats:
…Requires tiktoken: uv add tiktoken (benchmark features are optional)
| Type | Example Input | TOON Output |
|---|---|---|
| Object | {"name": "Alice", "age": 30} |
name: Alice |
age: 30 |
||
| Primitive Array | [1, 2, 3] |
[3]: 1,2,3 |
| Tabular Array | [{"id": 1, "name": "A"}, {"id": 2, "name": "B"}] |
[2,]{id,name}: |
1,A |
||
2,B |
||
| Mixed Array | [{"x": 1}, 42, "hi"] |
[3]: |
- x: 1 |
||
- 42 |
||
- hi |
Quoting: Only when necessary (empty, keywords, numeric strings, whitespace, structural chars, delimiters)
Type Normalization: Infinity/NaN/Functions → null • Decimal → float • datetime → ISO 8601 • -0 → 0
Adds a completely optional Pydantic integration via the [pydantic] extra.
pip install "toon-python[pydantic]"Instructor, Outlines, Marvin, LangChain agents, etc.from toon_format.pydantic import ToonPydanticModel
class User(ToonPydanticModel):
name: str
age: int
email: str | None = None
# Convert schema to TOON for LLM system prompts
schema_toon = User.schema_to_toon()
# name:str,age:int,email:str|None
# Parse LLM TOON output into validated Pydantic model
toon_output = "name:Ansar,age:25,email:[email protected]"
user = User.model_validate_toon(toon_output)
# user.name → "Ansar"
# user.age → 25
# user.email → "[email protected]"
# Serialize a model instance back to TOON
toon_str = user.model_dump_toon()# Setup (requires uv: https://docs.astral.sh/uv/)
git clone https://github.com/toon-format/toon-python.git
cd toon-python
uv sync
# Run tests (792 tests, 91% coverage, 85% enforced)
uv run pytest --cov=toon_format --cov-report=term
# Code quality
uv run ruff check src/ tests/ # Lint
uv run ruff format src/ tests/ # Format
uv run mypy src/ # Type checkCI/CD: GitHub Actions • Python 3.8-3.14 • Coverage enforcement • PR coverage comments
Following semantic versioning towards 1.0.0:
See CONTRIBUTING.md for detailed guidelines.
MIT License – see LICENSE for details
No open issues yet, or sync has not completed.