TOON: A Data Format for Language Models

Spec, Implementations, Paper (2025–2026)

TOON infographic: "Compact, human-readable serialization of JSON data for LLM prompts", a JSON to TOON to LLM workflow, a tabular example, and accuracy per 1K tokens at the bottom – 29.2 for TOON versus 16.6 for JSON.
Header of the IEEE Access research article "A Comprehensive Empirical Evaluation of Token-Oriented Object Notation (TOON) for Large Language Model Applications" with the five author names and the beginning of the abstract.
Title page of the IEEE Access paper "A Comprehensive Empirical Evaluation of Token-Oriented Object Notation (TOON) for Large Language Model Applications", with abstract, five author names, and a July 2026 publication date.
Page of the paper explaining TOON: a diagram of the pipeline from JSON through TOON to the language model, the same object side by side as JSON and as TOON, and an example of the tabular form at 22,250 versus 9,120 tokens.
Results page of the paper with four charts: overall accuracy by format with TOON leading at 73.9%, accuracy by model, the distribution of the 209 questions across five categories, and accuracy by question type.
Page of the paper with the validation accuracy table, a chart of token consumption by format, and a heatmap showing per dataset where TOON saves tokens and where it costs them.

tl;dr: In October 2025 I published a new data format: Token-Oriented Object Notation, TOON for short. As an example: a weather report costs 74 tokens in TOON instead of 161 as JSON.

location:
  city: Berlin
  country: DE
  units: metric
alerts[2]: frost,wind
forecast[3]{day,temp{min,max},condition,rainChance}:
  Mon,-2,4,snow,80
  Tue,1,7,cloudy,20
  Wed,3,11,sunny,5

Tokens are the building blocks a language model breaks text into before it reads it – and the unit inference providers bill by. The same data as JSON:

{
  "location": {
    "city": "Berlin",
    "country": "DE",
    "units": "metric"
  },
  "alerts": ["frost", "wind"],
  "forecast": [
    { "day": "Mon", "temp": { "min": -2, "max": 4 }, "condition": "snow", "rainChance": 80 },
    { "day": "Tue", "temp": { "min": 1, "max": 7 }, "condition": "cloudy", "rainChance": 20 },
    { "day": "Wed", "temp": { "min": 3, "max": 11 }, "condition": "sunny", "rainChance": 5 }
  ]
}

In forecast, the same six field names repeat for every day – day, temp, min, max, condition, rainChance. TOON writes them once into the header, below it only the values remain. On top of that comes the syntax itself: curly braces, quotation marks, colons, commas.

On large, uniform datasets, TOON needs 40 to 60 percent fewer tokens than JSON.

One thing actually costs tokens: the number in the brackets. forecast[3] announces three rows before the first one arrives. Reading, the model does not have to infer the count; writing, it has a target to check itself against.

The Byproduct of a Proof of Concept at Finanzfluss

In mid-2025, Thomas Kehl, my boss at Finanzfluss – Germany's largest personal finance platform – launched the daily news podcast im Loop together with Mary Abdelaziz-Ditzow. Monday through Friday, Mary and her team wanted to pursue the question of which of the day's news mattered for Germany and its economy.

So that the editorial team could set priorities for the episode each morning, someone had to compile beforehand what had happened across seven world regions in the last 24 hours. It quickly became clear that this daily workload could not be managed by hand.

Taken with the podcast idea, I built the briefing generator for Mary and her team, in production as a proof of concept from the start. The workflow runs as a web app that collects reports from around 270 news feeds every morning and has language models process them in several steps:

  • First the workflow reviews the reports per region and assigns each one to one of four categories: business, politics, finance, geopolitics. From several micro events across different sources it derives the overarching macro event.
  • In the second step the editorial team can select one or more macro events to be given a closer look.
  • Finally it reads the articles reporting on the macro event and generates the briefing from them.

The result is raw material, not a finished script.

The process still stands today, but the real question back then was: does the idea hold up at all, working the big topics of a day out of hundreds of individual reports? While the tool was taking shape, the editorial team got to see the finished prompt and could adjust it before it was sent. For them that was control, for me it was feedback. So a human had to be able to write in the format as well.

In the individual aggregation and evaluation steps, a great deal of data went to language models encoded as JSON – which made up the bulk of the prompts. That was unreadable and, on top of it, inefficient in terms of tokens.

For a plain table, CSV would have been enough. Around the reports, though, lay context nested several levels deep, which CSV cannot represent. I needed a mix of CSV and YAML – indentation for what was nested, a table for what was uniform; in a single document.

A Viral Repost on X

On October 22, 2025, I set the experiment up on GitHub: encoder and decoder in TypeScript, plus a README. The latter compared, across eight example datasets, how many tokens JSON and TOON cost, counted with the GPT tokenizer: 61 percent fewer. With no expectations, I published the format:

Johann Schopplich
@jschopplich

JSON is token‑expensive for LLMs – just like @mattpocockuk frequently mentions.

Meet TOON, the Token‑Oriented Object Notation.

πŸ’Έ 40–60% fewer tokens than JSON
πŸ“ readable & tokenizer-aware

Wrap your JSON with encode to save half the token cost: github.com/toon-format/toon

TOON infographic: "Compact, human-readable serialization of JSON data for LLM prompts", a JSON to TOON to LLM workflow, a tabular example, and accuracy per 1K tokens at the bottom – 29.2 for TOON versus 16.6 for JSON.
448 Retweets 3.5K Likes

Matt Pocock shared the post. Entirely unexpectedly, it went viral. Dozens of comments reached me every day; the star counter on GitHub stood at over 20k after a month. Handling that much attention was hard for me.

The response hit me like a wave, and on its crest stood two extremes. On one side, hype posts declaring TOON the JSON killer. On the other, rants, memes and the question of whether I had ever heard of CSV or YAML. Both fell short, and both hurt the idea in doing so. And both sowed doubt in me: does the idea really hold up?

Part of the CSV accusation I had brought on myself. The example I introduced the format with was a list of users with id, name and role. Flat, uniform, three columns. Anyone who saw only that saw a CSV table with a header line in front of it. That TOON handles nesting just as well was in the README, but what stuck was the badly chosen example. So for the first few weeks I spent several hours a day responding to comments, reposts and shitposts. I set half-knowledge straight and tried to take the wind out of the rants' sails.

Do Models Understand an Unknown Data Format?

Among the first comments was a question I had no answer to at that point: does a model understand TOON at all? I had measured the token reduction. Whether a language model reliably reads data out of a format it had never seen before was untested.

So I added a retrieval benchmark: the same datasets in every format, the same questions, counting how many answers were right. I compared TOON with CSV, XML, YAML, compact and formatted JSON.

The result came out better than I had dared hope: 69.2 percent correct answers against 65.4 for JSON, at 46.3 percent fewer tokens across the benchmark datasets. TOON was understood, and often read more accurately than JSON. Theo picked that up too:

Theo - t3.gg
@theo

Crazy how much more informed you can be by just reading the README file on the repo.

Armin is wrong here, the training data doesn't matter. TOON makes most models more accurate for lookup.

Bar chart from the TOON README: accuracy of four language models on 209 retrieval questions, TOON leading in each, at 73.9% versus JSON's 69.7%.
28 Retweets 642 Likes

In a video he ran the format through his own data. He found the weakness on his own – with nested, non-uniform data it lost to compactly written JSON. Even so, he ended up wanting to use it himself: anyone throwing hundreds of rows of uniform data at a model is better off with it than with JSON.

The Fight Against Ecosystem Fragmentation

A few days after my tweet, implementations in other languages sprang up: Java and Swift, then Go, Rust, Dart, .NET and Julia; half a dozen Python projects alone.

A young open source project can fray quickly at this point. Every implementation reads the details a little differently, so that after a few months the format is called the same everywhere but behaves differently. I reached out to the authors of the various repositories and invited them into a shared discussion. johannschopplich/toon became toon-format/toon, an organization with one official implementation per language.

That raised the question of what exactly they should align with. The format itself lived in the code: my TypeScript library was the definition of TOON. So on November 2, 2025, I added a specification in its own repository, along with a conformance test suite. The test cases are plain JSON files – input paired with expected output. That way every implementation could check its own encoder and decoder against them.

Moderating Community Feedback

With the attention came proposals to improve TOON. Everything from AI slop to well-considered spec fixes. Which of it belongs in the format, which only bloats it?

I let myself be tempted into building one of them in: key folding. The idea: if an object contains only a single key, which in turn contains only a single one, the chain can be pulled together into a path. Three indented lines become data.metadata.items. Sounds reasonable at first glance, since it saves characters. I built it into the encoder and the decoder without any further benchmarks.

In hindsight the feature brought complexity without benefit. Across all six benchmark datasets, key folding saved exactly 0.00 percent – chains of nothing but single-key objects practically never occur in real data. What weighed more was what it cost in return: the round trip. An object with the key a.b.c and a collapsed chain produce the same document, byte for byte – which of the two was meant could no longer be decided when decoding.

On top of that came three options for switching folding and unfolding on and off. The delimiter can be configured in TOON as well, only that one sits in the header: items[2|]. My three sat nowhere. Anyone who did not know the setting could not read the document back.

Version 4: Cleanups and Finalizing the Format

In July 2026, removing key folding was the commit that started TOON version 4. For this version I went through every open issue and pull request on GitHub. I cut duplicate rules from the specification, pinned down error cases that had stayed unspoken until then, and hardened encoder and decoder with new test cases. TOON now supports comment lines as well – the oldest issue of the specification. A line that begins with # the decoder throws away before it applies any other rule; the encoder never writes one itself.

For the first time since the first specification, two new forms were added. Both against the weakness Theo had found in the video: as soon as data was nested, TOON fell back to plain indentation.

The first is the nested field group. When a column of a table itself contains an object, and the same one in every row, that object moves up into the header and the rows stay flat. The example at the very top is a weather report for exactly that reason:

forecast[3]{day,temp{min,max},condition,rainChance}:
  Mon,-2,4,snow,80
  Tue,1,7,cloudy,20
  Wed,3,11,sunny,5

The second is the keyed tabular form, for objects whose values are all built the same way – configurations by environment, feature flags by name, records by ID. A colon after the length marks it, and every row carries its key up front:

environments[2:]{region,replicas,debug}:
  production: eu-central-1,6,false
  staging: eu-central-1,2,true

At the Low End of the Model Range

Again and again I picked up on X where TOON brought something. Jake Casto ran it in production at Layers, with Amazon Nova Micro:

Jake Casto
@0x15f

Yes I did. I’m using it in production w/ Amazon Nova Micro and it is performing better. We serve a ridiculous amount of ecomm traffic daily and have observed a clear drop in token usage and a decrease in ttfb from bedrock. The model did not perform well with CSVs or XML and did not even handle large compressed JSON well. For this model it is a win across the board

The gain was largest where models were weakest; for Jake the same model failed on CSV and on XML. How far down that carries I had not known – my own benchmarks ran against four models from large labs. I had published TOON because tokens cost money. Those who kept it in production did so because the answers were right.

An Email from Morocco

On November 17, 2025, an email from Morocco reached me. Khadija Ahaidous of EMSI in Casablanca wanted to examine TOON scientifically and asked for my measurement data. That a paper on TOON would yield anything I still doubted at that moment.

Six weeks later her draft was in front of me. The science was her work, the format mine: I checked whether what it said about TOON was correct, and insisted on naming the conflict of interest – I am the author of the format being evaluated here.

This year the paper appeared in IEEE Access. I am listed third of five authors. Behind it are 5,016 individual measurements: six formats, four models, seven tokenizer families, 209 questions on datasets from flat to deeply nested, measured against the version before the overhaul.

They are the same numbers as in my README, this time with confidence intervals. Three findings I took away:

  • The lead depends on the model. With GPT-5-nano, the strongest model in the test at the time, TOON and compact JSON came out even. With Gemini 2.5 Flash it was 87.6 against 77.0 percent.
  • On nested data TOON lost. 6 to 20 percent more tokens than compact JSON. The paper's advice is accordingly to check, before using it, how tabular your own data actually is.
  • No model noticed missing rows. When three were removed from the end, it went unnoticed in every single case. With too many rows it caught on in three out of four cases.

The finding hit the model, not the format. A strict decode aborts at the first discrepancy, and has done since the decoder has existed – anyone who has to rely on completeness lets the decoder check, not the model.


When I published TOON, this distinction still existed: reasoning models that think before answering, and ones that answer directly. Back then the fast, cheap models were still predominantly the ones without. Today the separation has practically vanished among frontier models; with some, reasoning can only be turned down to a minimum.

That shifts the math. Reasoning tokens are billed as output, and output costs a multiple of input. How many there will be is the model's decision. The saving on the input side therefore matters less than it did in 2025. That leaves the second reason: models read more reliably from explicitly structured data. That shrinks too, the better models get. In my current benchmark, TOON and JSON come out even on accuracy. Missing rows the models now notice themselves – in TOON, while they read right past them in JSON and YAML. Where models have to be small and fast, the difference remains.

A year ago I wrote on X: "If it turns out the idea is bad, it'll die in public too."