| Crates.io | toon |
| lib.rs | toon |
| version | 0.1.2 |
| created_at | 2025-10-29 05:13:02.6233+00 |
| updated_at | 2025-10-29 12:33:56.973337+00 |
| description | Token-Oriented Object Notation โ a token-efficient JSON alternative for LLM prompts |
| homepage | |
| repository | https://github.com/JadJabbour/toon-rs |
| max_upload_size | |
| id | 1906087 |
| size | 42,898 |
A Rust 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.
This is a Rust port of the original JavaScript/TypeScript implementation: @byjohann/toon.
LLM tokens cost money, and standard JSON is verbose. TOON conveys the same information with 30-60% fewer tokens than JSON:
JSON (257 tokens):
{
"users": [
{ "id": 1, "name": "Alice", "role": "admin" },
{ "id": 2, "name": "Bob", "role": "user" }
]
}
TOON (166 tokens):
users[2]{id,name,role}:
1,Alice,admin
2,Bob,user
Add this to your Cargo.toml:
[dependencies]
toon = "0.1.0"
serde_json = "1.0"
use toon::encode;
use serde_json::json;
fn main() {
let data = json!({
"user": {
"id": 123,
"name": "Ada",
"tags": ["reading", "gaming"],
"active": true
}
});
let toon_output = encode(&data, None);
println!("{}", toon_output);
}
Output:
user:
active: true
id: 123
name: Ada
tags[2]: reading,gaming
use toon::encode;
use serde_json::json;
let data = json!({
"id": 123,
"name": "Ada",
"active": true
});
println!("{}", encode(&data, None));
Output:
active: true
id: 123
name: Ada
let data = json!({
"items": [
{ "sku": "A1", "qty": 2, "price": 9.99 },
{ "sku": "B2", "qty": 1, "price": 14.5 }
]
});
println!("{}", encode(&data, None));
Output:
items[2]{price,qty,sku}:
9.99,2,A1
14.5,1,B2
Use tab or pipe delimiters for even more token savings:
use toon::{encode, EncodeOptions, Delimiter};
let data = json!({
"tags": ["reading", "gaming", "coding"]
});
let mut options = EncodeOptions::default();
options.delimiter = Delimiter::Tab;
println!("{}", encode(&data, Some(options)));
Output:
tags[3 ]: reading gaming coding
Add a # prefix to array lengths for clarity:
let mut options = EncodeOptions::default();
options.length_marker = Some('#');
let data = json!({"tags": ["a", "b", "c"]});
println!("{}", encode(&data, Some(options)));
Output:
tags[#3]: a,b,c
encode(value: &serde_json::Value, options: Option<EncodeOptions>) -> StringConverts a serde_json::Value to TOON format.
Parameters:
value: A reference to a serde_json::Value to encodeoptions: Optional encoding options (defaults to standard TOON format)Returns: A String containing the TOON-formatted output
EncodeOptionspub struct EncodeOptions {
pub indent: usize, // Spaces per indentation level (default: 2)
pub delimiter: Delimiter, // Delimiter for arrays (default: Comma)
pub length_marker: Option<char>, // Optional length prefix (default: None)
}
Delimiterpub enum Delimiter {
Comma, // ,
Tab, // \t
Pipe, // |
}
key: value with 2-space indentation for nestingtags[3]: a,b,citems[2]{id,name}:- prefixPython bindings are available in the pybinding/ directory.
pip install toon-python
Or build from source:
cd pybinding
pip install maturin
maturin build --release
pip install target/wheels/*.whl
import json
import toon
data = {
"users": [
{"id": 1, "name": "Alice", "role": "admin"},
{"id": 2, "name": "Bob", "role": "user"}
]
}
result = toon.encode(json.dumps(data))
print(result)
Output:
users[2]{id,name,role}:
1,Alice,admin
2,Bob,user
cd pybinding
maturin build --release
pip install twine
twine upload target/wheels/*
MIT License ยฉ 2025
Original JS/TS implementation: @byjohann/toon