<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John DeRegnaucourt</title>
    <description>The latest articles on DEV Community by John DeRegnaucourt (@john_deregnaucourt).</description>
    <link>https://dev.to/john_deregnaucourt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2798682%2F2d6b26f3-707f-423a-93b9-05e16471499a.jpg</url>
      <title>DEV Community: John DeRegnaucourt</title>
      <link>https://dev.to/john_deregnaucourt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/john_deregnaucourt"/>
    <language>en</language>
    <item>
      <title>Cut Your LLM Token Costs 40-50% — Java TOON Support in json-io</title>
      <dc:creator>John DeRegnaucourt</dc:creator>
      <pubDate>Sun, 25 Jan 2026 00:44:53 +0000</pubDate>
      <link>https://dev.to/john_deregnaucourt/java-finally-gets-toon-support-json-io-4850-bpp</link>
      <guid>https://dev.to/john_deregnaucourt/java-finally-gets-toon-support-json-io-4850-bpp</guid>
      <description>&lt;p&gt;Every time your Spring AI tool call returns a JSON result to the LLM, roughly half the tokens are syntactic noise — braces, brackets, quotes, and repeated key names. You're paying for punctuation.&lt;/p&gt;

&lt;p&gt;I maintain &lt;a href="https://github.com/jdereg/json-io" rel="noopener noreferrer"&gt;json-io&lt;/a&gt; (listed on &lt;a href="https://json.org" rel="noopener noreferrer"&gt;json.org&lt;/a&gt;). When I saw the excellent TOON articles here on Dev.to (&lt;a href="https://dev.to/akki907/toon-vs-json-the-new-format-designed-for-ai-nk5"&gt;this one&lt;/a&gt;, &lt;a href="https://dev.to/shishsingh/toon-a-lightweight-data-format-that-helps-cut-llm-token-costs-211i"&gt;this one&lt;/a&gt;) and noticed Java was underserved, I added full &lt;a href="https://toonformat.dev/" rel="noopener noreferrer"&gt;TOON&lt;/a&gt; support. Here's what it looks like, why it matters, and how to drop it into your Spring AI stack today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: JSON's Token Tax
&lt;/h2&gt;

&lt;p&gt;When an LLM calls a tool and gets back structured data, that data is serialized — almost always as JSON. The LLM tokenizes it and feeds it into its context window. Consider this tool call result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"employees"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Alice Johnson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Engineering"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"salary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;95000&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Bob Smith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Marketing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"salary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;78000&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Charlie Brown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Engineering"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"salary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;72000&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every key is quoted and repeated on every row, every object gets braces, the array gets brackets. The LLM doesn't need any of that structure to understand the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What TOON Looks Like
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://toonformat.dev/" rel="noopener noreferrer"&gt;TOON&lt;/a&gt; (Token-Oriented Object Notation) is an open format (&lt;a href="https://github.com/toon-format/spec" rel="noopener noreferrer"&gt;spec v3.0&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Token-Oriented_Object_Notation" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;) designed specifically for LLM token optimization. The same employee data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;employees[3]{name,age,department,salary}:
  Alice Johnson,28,Engineering,95000
  Bob Smith,34,Marketing,78000
  Charlie Brown,22,Engineering,72000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No braces or brackets&lt;/strong&gt; — structure comes from indentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No quotes&lt;/strong&gt; on keys or values (unless a value contains special characters)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Column headers stated once&lt;/strong&gt; — &lt;code&gt;{name,age,department,salary}&lt;/code&gt; replaces repeating every key on every row&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full fidelity&lt;/strong&gt; — this round-trips back to the same Java objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For nested objects, TOON uses indentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Alice Johnson&lt;/span&gt;
&lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;123 Main St&lt;/span&gt;
  &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Denver&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With key folding enabled, it can flatten one level for even more token savings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Alice Johnson&lt;/span&gt;
&lt;span class="py"&gt;address.street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;123 Main St&lt;/span&gt;
&lt;span class="py"&gt;address.city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Denver&lt;/span&gt;
&lt;span class="py"&gt;address.state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Numbers: Measured Token Savings
&lt;/h2&gt;

&lt;p&gt;We measured token counts using OpenAI's &lt;code&gt;o200k_base&lt;/code&gt; tokenizer (GPT-4o/4.1) across different payload sizes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Payload&lt;/th&gt;
&lt;th&gt;JSON Tokens&lt;/th&gt;
&lt;th&gt;TOON Tokens&lt;/th&gt;
&lt;th&gt;Savings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3 employees, 4 fields&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;24%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 employees, 4 fields&lt;/td&gt;
&lt;td&gt;206&lt;/td&gt;
&lt;td&gt;121&lt;/td&gt;
&lt;td&gt;41%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20 employees, 4 fields&lt;/td&gt;
&lt;td&gt;413&lt;/td&gt;
&lt;td&gt;231&lt;/td&gt;
&lt;td&gt;44%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25 products, 5 fields&lt;/td&gt;
&lt;td&gt;680&lt;/td&gt;
&lt;td&gt;459&lt;/td&gt;
&lt;td&gt;33%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern: &lt;strong&gt;savings scale with repetition&lt;/strong&gt;. A single object saves ~5%. But tool calls rarely return a single object — they return lists of records, search results, database rows. That's where TOON's tabular format delivers 30-50% reduction in token costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Usage — Two Lines of Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Any Java object -&amp;gt; TOON&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonIo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toToon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// TOON -&amp;gt; typed Java object&lt;/span&gt;
&lt;span class="nc"&gt;Employee&lt;/span&gt; &lt;span class="n"&gt;emp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonIo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromToon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toon&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;asClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Works with generics&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonIo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromToon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toon&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TypeHolder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;(){});&lt;/span&gt;

&lt;span class="c1"&gt;// TOON -&amp;gt; Maps (no class definition needed)&lt;/span&gt;
&lt;span class="nc"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonIo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromToon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toon&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;asMap&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spring AI Integration: One Annotation
&lt;/h2&gt;

&lt;p&gt;If you're using Spring AI for LLM tool calling, you can reduce token costs without changing any application logic. Add the dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.cedarsoftware&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;json-io-spring-ai-toon&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.98.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then annotate your tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Tool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Look up employees by department"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;resultConverter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ToonToolCallResultConverter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getEmployees&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employeeRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByDepartment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The &lt;code&gt;ToonToolCallResultConverter&lt;/code&gt; serializes the return value to TOON before it enters the LLM's context. Every tool call result is now 40-50% smaller.&lt;/p&gt;

&lt;p&gt;Programmatic registration works too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;FunctionToolCallback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"getEmployees"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getEmployees&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toolCallResultConverter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToonToolCallResultConverter&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Structured Output Parsing
&lt;/h3&gt;

&lt;p&gt;TOON works in both directions. When you want the LLM to &lt;em&gt;respond&lt;/em&gt; with structured data, &lt;code&gt;ToonBeanOutputConverter&lt;/code&gt; teaches it to respond in TOON instead of JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ToonBeanOutputConverter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToonBeanOutputConverter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Get info about John"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;converter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The converter generates format instructions for the LLM and parses TOON responses back into typed Java objects. The LLM produces fewer output tokens too — you save on both sides.&lt;/p&gt;

&lt;p&gt;For generic types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ToonBeanOutputConverter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToonBeanOutputConverter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TypeHolder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;()&lt;/span&gt; &lt;span class="o"&gt;{});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;json-io&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ai&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tool-call&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;key-folding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;      &lt;span class="c1"&gt;# Flatten nested keys (default: true)&lt;/span&gt;
      &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;strict-toon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;     &lt;span class="c1"&gt;# Permissive parsing for LLM output (default)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spring Boot REST Integration
&lt;/h2&gt;

&lt;p&gt;json-io also has a Spring Boot starter for REST APIs that support JSON, JSON5, and TOON via content negotiation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.cedarsoftware&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;json-io-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.98.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your existing REST controllers automatically gain TOON support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Request TOON format&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/vnd.toon"&lt;/span&gt; http://localhost:8080/api/employees
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No controller changes needed. Supports both Spring MVC and WebFlux.&lt;/p&gt;

&lt;h2&gt;
  
  
  But Can LLMs Actually Read TOON?
&lt;/h2&gt;

&lt;p&gt;Yes. LLMs don't parse JSON structurally — they understand it from training data. TOON's indentation-based format is similar enough to YAML, Python, and other whitespace-significant formats that current LLMs (GPT-4o, Claude, Gemini) handle it without issues. A &lt;a href="https://www.freecodecamp.org/news/what-is-toon-how-token-oriented-object-notation-could-change-how-ai-sees-data/" rel="noopener noreferrer"&gt;FreeCodeCamp article&lt;/a&gt; covers the accuracy testing — TOON actually achieved slightly &lt;em&gt;higher&lt;/em&gt; accuracy (74%) vs JSON (70%) in mixed-structure benchmarks across 4 models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Savings Come From
&lt;/h2&gt;

&lt;p&gt;It's worth understanding why the savings vary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single objects&lt;/strong&gt;: ~5% savings. Keys are stated once in both formats; TOON just drops the quotes and braces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lists of uniform objects&lt;/strong&gt;: 30-44% savings. This is the sweet spot. JSON repeats every key name on every object. TOON's tabular format states them once as column headers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deeply nested structures&lt;/strong&gt;: 3-10% savings. Indentation overhead partially offsets bracket/brace savings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tool call results are overwhelmingly lists of records — exactly where TOON performs best. If you're running LLM agents or RAG pipelines that pass structured data through context windows, TOON reduces both cost-per-token spend and context window consumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why json-io?
&lt;/h2&gt;

&lt;p&gt;json-io handles things Jackson and Gson can't — cyclic object graphs, automatic polymorphic types, 25+ annotations (including Jackson annotation compatibility with zero compile-time dependency) — all with zero configuration. 60+ built-in Java types, JDK 8-24, ~1MB total footprint. It reads JSON, JSON5, and TOON, and writes all three formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.cedarsoftware&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;json-io&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.98.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jdereg/json-io" rel="noopener noreferrer"&gt;json-io on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://toonformat.dev/" rel="noopener noreferrer"&gt;TOON format specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/java-json-toon-format-libraries" rel="noopener noreferrer"&gt;Baeldung: TOON Format Libraries in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jdereg/json-io/blob/master/user-guide-spring.md" rel="noopener noreferrer"&gt;Spring Integration Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/what-is-toon-how-token-oriented-object-notation-could-change-how-ai-sees-data/" rel="noopener noreferrer"&gt;FreeCodeCamp: How TOON Could Change How AI Sees Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're running Spring AI tool calls in production, I'd be curious to hear what token savings you see on your actual payloads. The 40-50% range has been consistent in our benchmarks, but real-world data is always more interesting.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>java</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
