<?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: Shank</title>
    <description>The latest articles on DEV Community by Shank (@mugen_shank).</description>
    <link>https://dev.to/mugen_shank</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%2F4177222%2F706688d5-236d-456e-aea1-13fa4e4675b1.jpg</url>
      <title>DEV Community: Shank</title>
      <link>https://dev.to/mugen_shank</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mugen_shank"/>
    <language>en</language>
    <item>
      <title>Why your JSON formatter silently changes your IDs</title>
      <dc:creator>Shank</dc:creator>
      <pubDate>Sun, 11 Oct 2026 15:00:04 +0000</pubDate>
      <link>https://dev.to/mugen_shank/why-your-json-formatter-silently-changes-your-ids-20ga</link>
      <guid>https://dev.to/mugen_shank/why-your-json-formatter-silently-changes-your-ids-20ga</guid>
      <description>&lt;p&gt;I needed a clean JSON tool. The ones I found came with ads all over the editor, cookie walls, "create an account to format this JSON", and no idea where my pasted data was going.&lt;/p&gt;

&lt;p&gt;So I built my own, and along the way I learned about something worse than clutter: paste a big ID into a lot of JSON tools and it comes back &lt;strong&gt;different&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// What you paste&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;order_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9007199254740993&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// What a typical formatter shows you&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;order_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9007199254740992&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No warning. No error. Just a different number, off by one, that looks perfectly normal. Copy that ID into a support ticket or a database query and you're chasing an order that doesn't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it happens
&lt;/h2&gt;

&lt;p&gt;Most JSON tools on the web do roughly this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pretty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;null&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is in the middle. &lt;code&gt;JSON.parse&lt;/code&gt; turns every number into a JavaScript &lt;code&gt;Number&lt;/code&gt;, which is a 64-bit floating point value. Floats can only store whole numbers exactly up to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_SAFE_INTEGER&lt;/span&gt; &lt;span class="c1"&gt;// 9007199254740991&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above that, there aren't enough bits, so the number gets rounded to the nearest one a float &lt;em&gt;can&lt;/em&gt; hold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"id": 9007199254740993}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="c1"&gt;// 9007199254740992&lt;/span&gt;

&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12345678901234567890&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 12345678901234567000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;JSON.stringify&lt;/code&gt; writes the rounded value back out, and it looks completely normal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this actually bites
&lt;/h2&gt;

&lt;p&gt;It's not just a curiosity. Big integers show up all the time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database IDs&lt;/strong&gt;: &lt;code&gt;BIGINT&lt;/code&gt; primary keys and Snowflake-style IDs easily go past 2⁵³.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social and chat platforms&lt;/strong&gt;: Twitter/X famously had to add &lt;code&gt;id_str&lt;/code&gt; to its API for exactly this reason, and Discord sends its IDs as strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments and tracking numbers&lt;/strong&gt;: anything long and numeric that was never meant to be "math".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one of those passes through a tool that parses it as a &lt;code&gt;Number&lt;/code&gt;, you get a valid-looking ID that points to the wrong thing, or to nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to avoid it in your own code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Send big IDs as strings.&lt;/strong&gt; This is the real fix. &lt;code&gt;"9007199254740993"&lt;/code&gt; survives everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. If you can't change the API, don't parse those numbers as &lt;code&gt;Number&lt;/code&gt;.&lt;/strong&gt; Newer JavaScript engines (recent Chrome and Node) let a reviver see the original text of each value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;order_id&lt;/span&gt; &lt;span class="c1"&gt;// 9007199254740993n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On older runtimes, a library like &lt;code&gt;json-bigint&lt;/code&gt; does the same job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Be careful with tools.&lt;/strong&gt; Formatters, log viewers and "pretty print" browser extensions often parse first and print second. If an ID matters, check that the tool doesn't touch number values.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I built a cleaner one
&lt;/h2&gt;

&lt;p&gt;I wanted a JSON formatter that never touches my data, without the usual nonsense: no ads covering the editor, no "create an account to format this JSON", and nothing uploaded to a server.&lt;/p&gt;

&lt;p&gt;I couldn't find one I liked, so I made it: &lt;strong&gt;&lt;a href="https://codeswatch.dev" rel="noopener noreferrer"&gt;CodeSwatch&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Big numbers stay exact.&lt;/strong&gt; It uses its own parser that keeps every number as the text you wrote, so &lt;code&gt;9007199254740993&lt;/code&gt; stays &lt;code&gt;9007199254740993&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plain-English errors&lt;/strong&gt; with the line and column, and a jump to the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repair JSON&lt;/strong&gt;: fixes trailing commas, single quotes, comments, &lt;code&gt;True&lt;/code&gt;/&lt;code&gt;None&lt;/code&gt;, missing brackets and cut-off data in one click. Handy for JSON that came out of an LLM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folds like VS Code&lt;/strong&gt;, with a path bar that shows where you are (&lt;code&gt;root › items › [3] › id&lt;/code&gt;) and copies it as JSONPath.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs in your browser.&lt;/strong&gt; Nothing you paste is sent anywhere, so it's fine for real API responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also has a JWT decoder, a timestamp converter, Base64 and a few color tools, all in the same spirit.&lt;/p&gt;

&lt;p&gt;It's free. I needed a clean tool, so I made it. Here you go. 🙂&lt;/p&gt;

&lt;p&gt;If something breaks or you want a tool added, I'd love to hear it in the comments.&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
