<?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: Ahmet Zencirli</title>
    <description>The latest articles on DEV Community by Ahmet Zencirli (@ahmet_zencirli).</description>
    <link>https://dev.to/ahmet_zencirli</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4221635%2F62120515-87e4-452d-9ed7-1e183be90f8e.jpeg</url>
      <title>DEV Community: Ahmet Zencirli</title>
      <link>https://dev.to/ahmet_zencirli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahmet_zencirli"/>
    <language>en</language>
    <item>
      <title>I stopped sending JSON keys to my LLM 100 times. Here's what it saved (and where it didn't)</title>
      <dc:creator>Ahmet Zencirli</dc:creator>
      <pubDate>Mon, 02 Nov 2026 11:21:25 +0000</pubDate>
      <link>https://dev.to/ahmet_zencirli/i-stopped-sending-json-keys-to-my-llm-100-times-heres-what-it-saved-and-where-it-didnt-59d2</link>
      <guid>https://dev.to/ahmet_zencirli/i-stopped-sending-json-keys-to-my-llm-100-times-heres-what-it-saved-and-where-it-didnt-59d2</guid>
      <description>&lt;p&gt;Look at the next tool result your agent gets back from an API. Something like this:&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"A-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"assignee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ann"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"labels"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="s2"&gt;"bug"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"A-2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"closed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"assignee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"labels"&lt;/span&gt;&lt;span class="p"&gt;:[]},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;...&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;Now imagine 100 rows. The words &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;assignee&lt;/code&gt; and &lt;code&gt;labels&lt;/code&gt; are sent 100 times each, with quotes around every one. The model doesn't need them 100 times. It needs them once.&lt;/p&gt;

&lt;p&gt;That's the whole idea behind &lt;strong&gt;LWON (Lightweight Object Notation)&lt;/strong&gt;: JSON with the keys written once. A header names the fields; the body holds only the values, by position.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like
&lt;/h2&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="err"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;city&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;sku&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;qty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;price&lt;/span&gt;&lt;span class="p"&gt;]]]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;page&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;A&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Ann&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Istanbul&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="err"&gt;SKU&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.99&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;SKU&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;19.5&lt;/span&gt;&lt;span class="p"&gt;]]]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;A&lt;/span&gt;&lt;span class="mi"&gt;-2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Bob&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Izmir&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;That is exactly this JSON:&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;"orders"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"A-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"customer"&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;"Ann"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Istanbul"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"SKU1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"qty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;9.99&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"SKU2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"qty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;19.5&lt;/span&gt;&lt;span class="p"&gt;}]},{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"A-2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"customer"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Izmir"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:[]}],&lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&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;Line 1 is the shape. Every row after it is just values. Nested objects and arrays of objects get their own fields in the header, so it stays compact even when the data isn't a flat table.&lt;/p&gt;

&lt;p&gt;The hard requirement I set for myself: &lt;strong&gt;any JSON value must convert to LWON and back without loss.&lt;/strong&gt; Escapes, &lt;code&gt;null&lt;/code&gt; versus a missing key, objects with different fields, weird keys, primitive roots. The test suite runs a language-neutral conformance set plus 3000 fuzzed round trips.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Isn't this just TOON / CSV?"
&lt;/h2&gt;

&lt;p&gt;Fair question. &lt;a href="https://github.com/toon-format/toon" rel="noopener noreferrer"&gt;TOON&lt;/a&gt; has the same goal and is very good on flat tables. CSV is fine until your data has nesting.&lt;/p&gt;

&lt;p&gt;The difference shows up on the data agents actually see: API responses with nested objects, trees, and optional fields. Here are Claude token counts (via the &lt;code&gt;count_tokens&lt;/code&gt; API) on six datasets:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dataset&lt;/th&gt;
&lt;th&gt;JSON (minified)&lt;/th&gt;
&lt;th&gt;TOON&lt;/th&gt;
&lt;th&gt;LWON&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flat table, 100 rows&lt;/td&gt;
&lt;td&gt;4295&lt;/td&gt;
&lt;td&gt;2510&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2503&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nested orders&lt;/td&gt;
&lt;td&gt;8259&lt;/td&gt;
&lt;td&gt;7435&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4808&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub-style issues&lt;/td&gt;
&lt;td&gt;4378&lt;/td&gt;
&lt;td&gt;4414&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2760&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recursive menu&lt;/td&gt;
&lt;td&gt;562&lt;/td&gt;
&lt;td&gt;578&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;362&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs with optional fields&lt;/td&gt;
&lt;td&gt;4393&lt;/td&gt;
&lt;td&gt;4472&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3452&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search tool result&lt;/td&gt;
&lt;td&gt;2930&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2200&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2298&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On flat tables LWON and TOON are basically tied, and TOON wins the search result. On nested and recursive data, LWON is 21–42% smaller than minified JSON, while table formats fall back to layouts close to JSON's size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fewer tokens is worthless if the model gets it wrong
&lt;/h2&gt;

&lt;p&gt;This was the part I cared about most. A format that saves 40% and makes the model misread a field is a net loss.&lt;/p&gt;

&lt;p&gt;So I wrote an eval: 44 questions about the benchmark data (lookups, counts, nested fields, trees, &lt;em&gt;absent versus null&lt;/em&gt;), asked in JSON, TOON and LWON, to Claude Haiku, Sonnet and Opus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every model got every question right in all three formats.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then I made it harder: 150 sparse log events where most fields are missing in most rows. Here LWON missed 11 of 176 answers and JSON missed 9. All misses in both formats were counts over many rows off by one to three, or a sum.&lt;/p&gt;

&lt;p&gt;I want to be upfront about that: on very sparse data, LWON is slightly behind JSON on accuracy, not ahead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing I got wrong in 0.x
&lt;/h2&gt;

&lt;p&gt;Input tokens are not the whole bill. Models &lt;em&gt;think&lt;/em&gt; about the data, and output tokens cost more than input.&lt;/p&gt;

&lt;p&gt;In LWON 0.x, every key was written by position, so sparse rows looked like &lt;code&gt;[x ~ ~ ~ ~ ~ 3 ~ ~ ~]&lt;/code&gt;. The models had to count positions through all those &lt;code&gt;~&lt;/code&gt; placeholders, reasoned much longer, and on the sparse data a question cost &lt;strong&gt;up to 3× as much&lt;/strong&gt; as with JSON. Smaller input, bigger bill.&lt;/p&gt;

&lt;p&gt;The fix in 1.0: rare keys are written by name in a trailing &lt;code&gt;*&lt;/code&gt; slot. Common fields stay positional, rare ones stay readable.&lt;/p&gt;

&lt;p&gt;Counting everything (input, thinking, output), a question now costs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;21–25% less&lt;/strong&gt; than JSON on regular data sent once (2–15% less when cached)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9–11% less&lt;/strong&gt; on sparse data sent once, but &lt;strong&gt;6–9% more&lt;/strong&gt; when cached&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So: measure on &lt;em&gt;your&lt;/em&gt; data. That's why the repo ships the eval scripts, not just the numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your own JSON
&lt;/h2&gt;

&lt;p&gt;The quickest way to see if LWON helps you is the &lt;strong&gt;&lt;a href="https://ahmetzencirli.github.io/lwon-studio/playground" rel="noopener noreferrer"&gt;playground&lt;/a&gt;&lt;/strong&gt;. Paste any JSON, or load one of the benchmark datasets, and it converts both ways and shows the token count next to minified JSON.&lt;/p&gt;

&lt;p&gt;Everything runs in your browser; your data isn't sent anywhere. Tokens there are counted with the o200k tokenizer, so the exact numbers differ a little from Claude's, but the ratio is close.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @lwon/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PRIMER&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@lwon/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// any JSON value → LWON&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// LWON → the same JSON value&lt;/span&gt;

&lt;span class="c1"&gt;// Models don't know LWON yet, so send a short primer (~330 tokens) once.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PRIMER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One rule: convert &lt;strong&gt;before&lt;/strong&gt; the data reaches the model, in your tool or API layer. Asking the model to convert saves nothing.&lt;/p&gt;

&lt;p&gt;There's also a CLI if you want to check your own data first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @lwon/core stats data.json   &lt;span class="c"&gt;# JSON vs LWON size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Zero-code: an MCP proxy
&lt;/h2&gt;

&lt;p&gt;Most of the JSON my agents see comes from MCP tool results, so I wrote &lt;a href="https://github.com/ahmetzencirli/lwon/tree/main/packages/mcp-proxy" rel="noopener noreferrer"&gt;&lt;code&gt;@lwon/mcp-proxy&lt;/code&gt;&lt;/a&gt;. Put it in front of any stdio MCP server and large JSON tool results reach the model as LWON. The server doesn't change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add github &lt;span class="nt"&gt;--&lt;/span&gt; npx &lt;span class="nt"&gt;-y&lt;/span&gt; @lwon/mcp-proxy &lt;span class="nt"&gt;--&lt;/span&gt; npx &lt;span class="nt"&gt;-y&lt;/span&gt; @modelcontextprotocol/server-github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It only rewrites a result when it's JSON, at least 2000 characters, and at least 10% shorter as LWON. Errors, plain text, images and &lt;code&gt;structuredContent&lt;/code&gt; pass through untouched. The primer goes into the server's instructions once per session, not once per result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status and what I'd love feedback on
&lt;/h2&gt;

&lt;p&gt;LWON is &lt;strong&gt;1.0 beta&lt;/strong&gt;: the spec, a dependency-free TypeScript library, a conformance suite, and the MCP proxy, under Apache-2.0. Python and Go ports are next.&lt;/p&gt;

&lt;p&gt;I'd really like to hear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your data.&lt;/strong&gt; Paste a real tool result into the &lt;a href="https://ahmetzencirli.github.io/lwon-studio/playground" rel="noopener noreferrer"&gt;playground&lt;/a&gt; and tell me the number, especially if LWON loses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other models.&lt;/strong&gt; My evals are Claude-only so far. If you test GPT or Gemini, I'll add the results.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The spec.&lt;/strong&gt; If you find a JSON value that doesn't round-trip, that's a bug I want.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Playground: &lt;a href="https://ahmetzencirli.github.io/lwon-studio/playground" rel="noopener noreferrer"&gt;https://ahmetzencirli.github.io/lwon-studio/playground&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Website and spec: &lt;a href="https://ahmetzencirli.github.io/lwon-studio/" rel="noopener noreferrer"&gt;https://ahmetzencirli.github.io/lwon-studio/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub: &lt;a href="https://github.com/ahmetzencirli/lwon" rel="noopener noreferrer"&gt;https://github.com/ahmetzencirli/lwon&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>json</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
