<?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: unitstack</title>
    <description>The latest articles on DEV Community by unitstack (@unitstack).</description>
    <link>https://dev.to/unitstack</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%2F4161083%2F26a6e402-d8f5-4485-add3-09e1877f7189.jpg</url>
      <title>DEV Community: unitstack</title>
      <link>https://dev.to/unitstack</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/unitstack"/>
    <language>en</language>
    <item>
      <title>Shorten JSON Diff Time in AI Agents</title>
      <dc:creator>unitstack</dc:creator>
      <pubDate>Wed, 07 Oct 2026 07:29:46 +0000</pubDate>
      <link>https://dev.to/unitstack/shorten-json-diff-time-in-ai-agents-1coi</link>
      <guid>https://dev.to/unitstack/shorten-json-diff-time-in-ai-agents-1coi</guid>
      <description>&lt;p&gt;Ask an AI coding agent "what changed between these two JSON files?" and watch what it does. With small files you usually get a decent answer. With large ones — a minified API response, a 5,000-line fixture, a generated config — you typically get one of two failure modes: a wrong answer delivered with confidence, or a long, expensive hunt for the difference. The &lt;a href="https://comparejson.com/skills/" rel="noopener noreferrer"&gt;Compare JSON Skills&lt;/a&gt; and &lt;a href="https://comparejson.com/mcp/" rel="noopener noreferrer"&gt;Compare JSON MCP&lt;/a&gt; integrations exist to fix both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure mode 1: the git diff trap
&lt;/h2&gt;

&lt;p&gt;The first tool an agent reaches for is usually &lt;code&gt;git diff --no-index&lt;/code&gt; (or plain &lt;code&gt;diff&lt;/code&gt;). That's a line-based text diff, and JSON is not line-based data.&lt;/p&gt;

&lt;p&gt;The worst case is minified JSON — one line, tens of thousands of characters, extremely common in real API responses and snapshots:&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="nv"&gt;$ &lt;/span&gt;git diff &lt;span class="nt"&gt;--no-index&lt;/span&gt; base.json contrast.json
-&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;:1,&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"Alice"&lt;/span&gt;,&lt;span class="s2"&gt;"email"&lt;/span&gt;:&lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, ... 40,000 more characters
+&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;:1,&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"Alice"&lt;/span&gt;,&lt;span class="s2"&gt;"email"&lt;/span&gt;:&lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, ... 40,000 more characters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One field changed somewhere in the middle, and the diff reports "the line changed". The agent still has to locate the actual difference itself — inside a single 40 KB line. Some agents give up and guess, which is where confidently wrong answers come from.&lt;/p&gt;

&lt;p&gt;Even with pretty-printed files, text diff produces misleading hunks: reordered keys, whitespace changes, or one element inserted into an array can cascade into dozens of "changed" lines that don't correspond to any real data change. A smarter agent will pretty-print both sides with &lt;code&gt;jq&lt;/code&gt; first — better, but key order and array misalignment still generate noise. The agent faithfully summarizes that noise, and one change gets reported as a dozen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure mode 2: the eyeball marathon
&lt;/h2&gt;

&lt;p&gt;The other default strategy is to read both files into the context window and look for the difference. On a large file this turns into a marathon: the file gets truncated, the agent re-reads it in chunks, runs a few &lt;code&gt;grep&lt;/code&gt;s, scrolls back and forth — and several minutes and tens of thousands of tokens later, it announces that &lt;code&gt;meta.buildNumber&lt;/code&gt; went from &lt;code&gt;841&lt;/code&gt; to &lt;code&gt;842&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Correct, but slow, expensive, and fragile. Every extra tool call is another chance to truncate, misalign, or miss a second difference hiding elsewhere in the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: let a diff engine do the diffing
&lt;/h2&gt;

&lt;p&gt;JSON diffing is a solved problem — just not by text tools. Parse both documents into trees, align objects by key and arrays by a chosen strategy, and report changes as exact paths. Deterministic, immune to formatting, and fast:&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="nv"&gt;$ &lt;/span&gt;npx @compare-json/cli base.json contrast.json
valueChanged  meta.buildNumber
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line of output, no matter how large the inputs. The agent's job shrinks from &lt;em&gt;finding&lt;/em&gt; the difference to &lt;em&gt;explaining&lt;/em&gt; it — which is the part it's actually good at. That's the entire reason the skill and the MCP server exist: they put this engine one tool call away, so the comparison takes seconds instead of minutes, and the answer stops depending on how the files happened to be formatted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two ways to plug the engine in
&lt;/h2&gt;

&lt;p&gt;Same engine, two delivery mechanisms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;a href="https://comparejson.com/skills/" rel="noopener noreferrer"&gt;skill&lt;/a&gt;&lt;/strong&gt; is a single &lt;code&gt;SKILL.md&lt;/code&gt; that teaches your agent when and how to invoke &lt;a href="https://www.npmjs.com/package/@compare-json/cli" rel="noopener noreferrer"&gt;&lt;code&gt;@compare-json/cli&lt;/code&gt;&lt;/a&gt;. Install it once and any Agent Skills-compatible assistant — Claude Code, Codex CLI, OpenCode, Cursor — will run the CLI locally whenever you ask it to compare JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add unitstack/compare-json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The &lt;a href="https://comparejson.com/mcp/" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;&lt;/strong&gt; exposes the same comparison as a structured &lt;code&gt;compare_json&lt;/code&gt; tool. The CLI doubles as an MCP server (&lt;code&gt;--mcp&lt;/code&gt;), so any MCP-capable client can call it with two file paths or strings and get machine-readable differences back:&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"differences"&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="nl"&gt;"pathSegments"&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="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"buildNumber"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pathString"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meta.buildNumber"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pathBelongsTo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"both"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"diffType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"valueChanged"&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="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;Which one should you pick? If your assistant supports Agent Skills, the skill is the lighter touch — no server config, invoked on demand. If your client speaks MCP and you want a permanent, typed tool with structured output, use the MCP server. Both wrap the same engine, so they report identical differences — including the array comparison strategy and the case-insensitive options.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;LLMs are good at reasoning about differences and bad at locating them in raw text. The skill and the MCP server exist to split that work properly: the engine finds every difference in seconds, deterministically, and your agent spends its time — and your tokens — on the part that needs judgment.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>A Live Mermaid Theme Playground: mermaid.design</title>
      <dc:creator>unitstack</dc:creator>
      <pubDate>Sun, 04 Oct 2026 18:32:50 +0000</pubDate>
      <link>https://dev.to/unitstack/a-live-theme-playground-for-mermaid-mermaiddesign-f73</link>
      <guid>https://dev.to/unitstack/a-live-theme-playground-for-mermaid-mermaiddesign-f73</guid>
      <description>&lt;p&gt;I use Mermaid a lot — flowcharts in design docs, sequence diagrams in READMEs, the odd ER diagram. Diagrams-as-code is a great deal: versionable, diffable, no dragging boxes around a canvas. What was never great is how the result &lt;em&gt;looks&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The built-in themes are functional, but the colors feel dated. Mermaid does have a real theming system — set &lt;code&gt;theme: 'base'&lt;/code&gt; and override whatever you like in &lt;code&gt;themeVariables&lt;/code&gt;. The problem is the workflow: edit a frontmatter block, re-render, squint at the output, guess which of the 70-odd variables actually paints the thing you dislike, repeat.&lt;/p&gt;

&lt;p&gt;My breaking point was a sequence diagram. I changed &lt;code&gt;primaryColor&lt;/code&gt; and the actor boxes changed color along with it — turns out those belong to &lt;code&gt;actorBkg&lt;/code&gt;. Ten minutes per color, most of it guessing, because a variable's name tells you almost nothing about what it paints.&lt;/p&gt;

&lt;p&gt;What I wanted was simple: tweak a variable, see what it does. Immediately.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://mermaid.design" rel="noopener noreferrer"&gt;mermaid.design&lt;/a&gt; — Mermaid code on the left, a live preview in the middle, and the whole theme system editable on the right. Every change re-renders the diagram in place. The feedback loop went from minutes to seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx6ewh8jrul1p52uqmyhh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx6ewh8jrul1p52uqmyhh.png" alt="The mermaid.design editor: Mermaid code on the left, live diagram preview in the center, theme variables on the right" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's the pitch. Here are the parts that actually save time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gallery: every diagram type at a glance
&lt;/h2&gt;

&lt;p&gt;The annoying thing about theme variables is that the same variable behaves differently across diagram types. The gallery page renders all 84 templates — flowcharts, sequence, class, state, ER and more — live with your current theme. Change a variable, scroll the gallery, and the effect on every diagram type is right there. No more switching diagram types back and forth to check. That's the time it saves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theme variables: defaults and inheritance on the surface
&lt;/h2&gt;

&lt;p&gt;Every one of the 73 variables shows its default from the mermaid base theme. Variables you haven't set get an AUTO badge showing the value mermaid derives at render time — and where that value comes from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mainBkg&lt;/code&gt; follows &lt;code&gt;primaryColor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;primaryBorderColor&lt;/code&gt; is a border color computed from &lt;code&gt;primaryColor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secondaryTextColor&lt;/code&gt; is the inverse of &lt;code&gt;secondaryColor&lt;/code&gt; (for contrast)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actorBkg&lt;/code&gt; follows &lt;code&gt;mainBkg&lt;/code&gt; — which explains the trap from earlier: changing &lt;code&gt;primaryColor&lt;/code&gt; moved my actor boxes because there's an inheritance chain &lt;code&gt;primaryColor&lt;/code&gt; → &lt;code&gt;mainBkg&lt;/code&gt; → &lt;code&gt;actorBkg&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you see the chain, recoloring stops being guesswork.&lt;/p&gt;

&lt;h2&gt;
  
  
  Presets: official, designer, and more to come
&lt;/h2&gt;

&lt;p&gt;21 presets, one click to apply: the 11 official mermaid themes (default, neutral, dark, forest, base, plus the v12 redux and neo families) and 10 designer presets I tuned by hand. Each shows a live mini preview — and the collection keeps growing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate: one primary color, a whole palette
&lt;/h2&gt;

&lt;p&gt;Pick a single primary seed color and the generator ramps lightness in HSL space around its hue — an 8-step scale — to derive a complete palette, dark-mode variant included. The fastest way to make a diagram match your brand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render config: beyond colors
&lt;/h2&gt;

&lt;p&gt;Colors are only half of it. Mermaid has 438 render-affecting config fields, grouped by diagram type into 34 groups. A few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global: &lt;code&gt;fontFamily&lt;/code&gt;, &lt;code&gt;fontSize&lt;/code&gt;, &lt;code&gt;wrap&lt;/code&gt; (auto text wrapping), &lt;code&gt;look&lt;/code&gt; (classic or handDrawn)&lt;/li&gt;
&lt;li&gt;Flowchart: &lt;code&gt;flowchart.curve&lt;/code&gt; (edge curve style), &lt;code&gt;flowchart.nodeSpacing&lt;/code&gt; / &lt;code&gt;flowchart.rankSpacing&lt;/code&gt; (node/rank spacing), &lt;code&gt;flowchart.diagramPadding&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sequence: &lt;code&gt;sequence.actorMargin&lt;/code&gt;, &lt;code&gt;sequence.messageMargin&lt;/code&gt;, &lt;code&gt;sequence.showSequenceNumbers&lt;/code&gt; (message numbering), &lt;code&gt;sequence.mirrorActors&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pie: &lt;code&gt;pie.textPosition&lt;/code&gt;, &lt;code&gt;pie.donutHole&lt;/code&gt;, &lt;code&gt;pie.legendPosition&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The group matching your current diagram type opens automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  ASCII mode: diagrams as text
&lt;/h2&gt;

&lt;p&gt;The same diagram can render as ASCII art — one click to copy, ready for code comments, commit messages, or plain-text docs. It currently supports five diagram types: flowchart, sequence, class, state, and ER. The charset can be Unicode box-drawing or plain ASCII.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The motivation behind mermaid.design was simple: the official theme colors are hard to love, hand-tuning themeVariables is slow, and I wanted a place where every change shows its effect immediately. Today it has live-editable theme variables with visible defaults and inheritance, a gallery that shows every diagram type at once, official and designer presets, a generator that turns one primary color into a full palette, 438 render-config fields, and an ASCII mode that turns diagrams into text.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
