<?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>Forem: Figsy</title>
    <description>The latest articles on Forem by Figsy (@figsify).</description>
    <link>https://forem.com/figsify</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%2F2175536%2Fc8805edf-716f-4a35-a631-8d86c91f093f.jpg</url>
      <title>Forem: Figsy</title>
      <link>https://forem.com/figsify</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/figsify"/>
    <language>en</language>
    <item>
      <title>Elixir Comprehensions: Learn Enough to be Dangerous</title>
      <dc:creator>Figsy</dc:creator>
      <pubDate>Sat, 18 Apr 2026 23:50:34 +0000</pubDate>
      <link>https://forem.com/figsify/elixir-comprehensions-learn-enough-to-be-dangerous-3514</link>
      <guid>https://forem.com/figsify/elixir-comprehensions-learn-enough-to-be-dangerous-3514</guid>
      <description>&lt;p&gt;When you first encounter a &lt;code&gt;for&lt;/code&gt; comprehension in Elixir, it looks like a standard loop. But &lt;strong&gt;Elixir doesn't have traditional &lt;code&gt;for&lt;/code&gt; loops&lt;/strong&gt;. Instead, comprehensions are powerful pipelines for iterating, filtering, and transforming data all at once.&lt;/p&gt;

&lt;p&gt;To master comprehensions, we need to understand their anatomy. Let's look at the basic blueprint, and then scale it up to the advanced, infinite chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Simple Comprehension &lt;em&gt;(like a simple &lt;code&gt;Enum.map&lt;/code&gt;)&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;The absolute simplest comprehension has one &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; and an &lt;code&gt;&amp;lt;expression&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;generator&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;expression&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, in its single-line form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;generator&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;expression&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [10, 20, 30]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [10, 20, 30]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of it like a simple &lt;code&gt;Enum.map&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [10, 20, 30]&lt;/span&gt;

&lt;span class="c1"&gt;# Or&lt;/span&gt;

&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [10, 20, 30]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2F43mjoj97sif2hxfqqy3i.gif" 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.amazonaws.com%2Fuploads%2Farticles%2F43mjoj97sif2hxfqqy3i.gif" alt="Simple form of a Comprehension" width="560" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Adding Filters
&lt;/h2&gt;

&lt;p&gt;You can add a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; immediately after your &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; to discard items you don't want. You aren't limited to just one; you can add multiple &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;s in a row.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as every &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; evaluates to "truthiness" (anything other than &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt;), the comprehension continues to the next step. If any &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; evaluates to &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt;, the item is immediately skipped.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤔 How does Elixir know it's a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Elixir figures it out by process of elimination. If an expression in your comma-separated list&lt;br&gt;
&lt;em&gt;(1)&lt;/em&gt; doesn't have an &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; arrow (&lt;code&gt;&amp;lt;-&lt;/code&gt;),&lt;br&gt;
&lt;em&gt;(2)&lt;/em&gt; isn't a predefined option (like &lt;code&gt;into:&lt;/code&gt;, &lt;code&gt;uniq:&lt;/code&gt;, or &lt;code&gt;reduce:&lt;/code&gt;),&lt;br&gt;
&lt;em&gt;(3)&lt;/em&gt; and isn't the &lt;code&gt;do&lt;/code&gt; block,&lt;br&gt;
Elixir automatically treats it as a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: ~c"&amp;lt;Pd"&lt;/span&gt;

&lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;charlists:&lt;/span&gt; &lt;span class="ss"&gt;:as_lists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [60, 80, 100]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If IEx sees a list where every single number is a printable character, it tries to be "helpful" by printing it as a string of characters (prefixed with ~c).&lt;br&gt;
Because 60, 80, and 100 all fall within the "printable" range, Elixir shows you &lt;code&gt;&amp;lt;Pd&lt;/code&gt; instead of the numbers.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Ffypgta6uvj5imhhmgige.gif" 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.amazonaws.com%2Fuploads%2Farticles%2Ffypgta6uvj5imhhmgige.gif" alt="Adding Filters to Comprehension" width="600" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Adding Options
&lt;/h2&gt;

&lt;p&gt;You can also add &lt;code&gt;&amp;lt;options&amp;gt;&lt;/code&gt; at the very end of your setup (just before the &lt;code&gt;do&lt;/code&gt; block) to change the behavior of the loop or format the final output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🤔 How does Elixir recognize &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;s?&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt;s (which use &lt;code&gt;&amp;lt;-&lt;/code&gt;) or &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;s (which are arbitrary expressions), &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;s are recognized because they belong to a strictly predefined set of keywords built into the Elixir language. The most common ones are &lt;code&gt;into:&lt;/code&gt;, &lt;code&gt;uniq:&lt;/code&gt;, and &lt;code&gt;reduce:&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, using the predefined &lt;code&gt;into:&lt;/code&gt; keyword turns the output from a standard list into a map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;into:&lt;/span&gt; &lt;span class="p"&gt;%{}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: %{1 =&amp;gt; 10, 2 =&amp;gt; 20, 3 =&amp;gt; 30}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2F78vjkt0vzk90c27922oi.gif" 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.amazonaws.com%2Fuploads%2Farticles%2F78vjkt0vzk90c27922oi.gif" alt="Adding Options to Comprehension" width="560" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can mix and match &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;s (more than one) to change how data is collected. However, not all &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;s play well together.&lt;/p&gt;

&lt;p&gt;The most common combination is using &lt;code&gt;into:&lt;/code&gt; and &lt;code&gt;uniq:&lt;/code&gt; together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&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="mi"&gt;1&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;uniq:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;into:&lt;/span&gt; &lt;span class="p"&gt;%{}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: %{1 =&amp;gt; 1, 2 =&amp;gt; 4, 3 =&amp;gt; 9}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;reduce:&lt;/code&gt; is the "lone wolf". You cannot combine &lt;code&gt;reduce:&lt;/code&gt; with &lt;code&gt;into:&lt;/code&gt; because they are two different ways of handling the accumulation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"cherry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;reduce:&lt;/span&gt; &lt;span class="p"&gt;%{}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&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="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: %{"apple" =&amp;gt; 3, "banana" =&amp;gt; 2, "cherry" =&amp;gt; 1}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fgfiuop3h720fbv0cjyrk.gif" 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.amazonaws.com%2Fuploads%2Farticles%2Fgfiuop3h720fbv0cjyrk.gif" alt="Mix and Match Comprehension Options" width="200" height="218"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;reduce:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;initial_accumulator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;current_accumulator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;new_accumulator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;reduce:&lt;/code&gt; case, Elixir swaps the default collection behavior for a manual accumulation process. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;initial_accumulator&amp;gt;&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We provide an initial value (like &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;[]&lt;/code&gt;, or &lt;code&gt;%Base{}&lt;/code&gt;) which acts as the starting state for the accumulator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;current_accumulator&amp;gt; -&amp;gt; &amp;lt;new_accumulator&amp;gt;&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of the &lt;code&gt;do&lt;/code&gt; block simply returning a value to be added to a list, it acts as a &lt;strong&gt;reducing function&lt;/strong&gt; that takes the current accumulator on the left side of the &lt;code&gt;-&amp;gt;&lt;/code&gt; arrow.&lt;/li&gt;
&lt;li&gt;Whatever the expression on the right side returns becomes the new state of the accumulator for the very next iteration.&lt;/li&gt;
&lt;li&gt;Elixir skips the do block entirely and passes the unchanged accumulator forward, ensuring that by the time the &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; is exhausted, you are left with a single, final value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Adding Filters + Options
&lt;/h2&gt;

&lt;p&gt;Before jumping into &lt;strong&gt;Complex Chain&lt;/strong&gt;, let's combine these concepts. You can shape the data with a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; and change the output format with an &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are some examples that walk through the increasing complexity of Elixir comprehensions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4.1.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&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="mi"&gt;1&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# generator&lt;/span&gt;
  &lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter: find even numbers&lt;/span&gt;
  &lt;span class="ss"&gt;uniq:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# option: remove duplicates&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="c1"&gt;# expression&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [20, 40]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we use one &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; to find even numbers and the &lt;code&gt;uniq: true&lt;/code&gt; option to remove duplicates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4.2.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# generator&lt;/span&gt;
  &lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter: find even numbers&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter: find numbers &amp;gt; 5&lt;/span&gt;
  &lt;span class="ss"&gt;into:&lt;/span&gt; &lt;span class="p"&gt;%{},&lt;/span&gt; &lt;span class="c1"&gt;# option: collect the results in a Map&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Number &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# Result: %{6 =&amp;gt; "Number 6", 8 =&amp;gt; "Number 8", 10 =&amp;gt; "Number 10"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we use two &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;s to narrow down the list before collecting the results into a Map.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4.3.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# generator&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter: find numbers &amp;gt; 5&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter: find numbers &amp;lt; 11&lt;/span&gt;
  &lt;span class="ss"&gt;uniq:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# option: remove duplicates&lt;/span&gt;
  &lt;span class="ss"&gt;into:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;# option: collect the result in a List&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [12, 16, 20]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows the &lt;code&gt;uniq:&lt;/code&gt; and &lt;code&gt;into:&lt;/code&gt; working together. It filters the data and ensures the destination collection only receives unique keys.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4.4.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# generator 1&lt;/span&gt;
  &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# generator 2: every single x, it will try every possible value of y&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter 1&lt;/span&gt;
  &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# filter 2&lt;/span&gt;
  &lt;span class="ss"&gt;reduce:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# option&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Result: 43&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. The Complex Chain
&lt;/h2&gt;

&lt;p&gt;The true power of Elixir comprehensions lies in the &lt;strong&gt;Complex Chain&lt;/strong&gt;. A comprehension isn't limited to just one &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; or one &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;. You can string together as many steps as you want, in almost any order.&lt;/p&gt;

&lt;p&gt;The blueprint can take many forms depending on how you want to process your data. You can group all your data extraction first, followed by all your filtering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, you can interleave them step-by-step (which is highly recommended for performance):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as you start the entire comprehension with at least one &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt;, you can mix and match &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; combinations infinitely!&lt;/p&gt;

&lt;h2&gt;
  
  
  6. How Elixir Decodes the Syntax (The Clues)?
&lt;/h2&gt;

&lt;p&gt;With so many possible combinations, looking at a massive block of &lt;code&gt;for&lt;/code&gt; code can be intimidating. How does the engine know which part is a &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; and which is a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Elixir's compiler reads it very simply. It looks for specific "clues" in your comma-separated list to know exactly what a piece of code is supposed to do, regardless of the order you place them in:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clue&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The &lt;code&gt;&amp;lt;-&lt;/code&gt; symbol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If an element has an arrow, it is a &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt;. It means "pull data from this collection".&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Known Keywords (&lt;code&gt;into:&lt;/code&gt;, &lt;code&gt;uniq:&lt;/code&gt;, &lt;code&gt;reduce:&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If an element uses one of these keys, it is an &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;. It configures the final output.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The &lt;code&gt;do:&lt;/code&gt; or &lt;code&gt;do&lt;/code&gt; keyword&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;This marks the end of the setup and the beginning of the &lt;code&gt;&amp;lt;expression&amp;gt;&lt;/code&gt; (what you want to return for each item).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Everything Else&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If an element doesn't have an arrow (&lt;code&gt;&amp;lt;-&lt;/code&gt;), isn't an &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;, and isn't the &lt;code&gt;do&lt;/code&gt; block... it is a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. Execution Flow
&lt;/h2&gt;

&lt;p&gt;Because Elixir uses these simple clues, you don't have to put all &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt;s first and all &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;s last. You can interleave them.&lt;/p&gt;

&lt;p&gt;Let's look at how Elixir processes the chain: &lt;code&gt;&amp;lt;generator 1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;filter 1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;generator 2&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;filter 2&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generator 1&lt;/strong&gt; pulls the first item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter 1&lt;/strong&gt; evaluates that item.
&lt;em&gt;(a)&lt;/em&gt; If the &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt;'s &lt;strong&gt;truthiness&lt;/strong&gt; is &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt;, Elixir throws the item away, skips the rest of the chain, and asks &lt;strong&gt;Generator 1&lt;/strong&gt; for the next item.
&lt;em&gt;(b)&lt;/em&gt; If it evaluates to &lt;strong&gt;truthy&lt;/strong&gt; (e.g., &lt;code&gt;true&lt;/code&gt;, a number, a string), it passes the gate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generator 2&lt;/strong&gt; is now triggered. Because it sits after &lt;strong&gt;Generator 1&lt;/strong&gt;, it runs a full loop for every single item that survives &lt;strong&gt;Filter 1&lt;/strong&gt;. This creates a &lt;strong&gt;nested loop&lt;/strong&gt;, also known as a &lt;strong&gt;Cartesian Product&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter 2&lt;/strong&gt; evaluates the combined result of Generator &lt;strong&gt;1&lt;/strong&gt; and &lt;strong&gt;2&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example 7.1. Finding valid mixed colors from RGB channels
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 3 Generators Grouped&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Filter 1: No pure black&lt;/span&gt;
  &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;765&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="c1"&gt;# Filter 2: Nor pure white&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: [{0, 0, 255}, {0, 255, 0}, {0, 255, 255}, {255, 0, 0}, {255, 0, 255}, {255, 255, 0}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is useful when you need to &lt;strong&gt;calculate the entire Cartesian product first&lt;/strong&gt; before you have enough context to filter it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 7.2. Finding senior staff on high-performing teams at profitable companies.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;companies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"TechCorp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;profit:&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;teams:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;%{&lt;/span&gt;
        &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Alpha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;rating:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;members:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:senior&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:junior&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="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"BankInc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;profit:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;teams:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Unprofitable company&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;companies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;profit&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Filter 1: Skip losing companies instantly&lt;/span&gt;
  &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;teams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Filter 2: Skip low-rated teams instantly&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;member_name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:senior&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="c1"&gt;# Filter 3: Only keep senior members&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;member_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; from &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; at &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Result: ["Alice from Alpha at TechCorp"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fp7it30f8s59bdropf1wm.gif" 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.amazonaws.com%2Fuploads%2Farticles%2Fp7it30f8s59bdropf1wm.gif" alt="Complex Chain of Comprehension" width="80" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where Elixir shines. By placing a &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; immediately after its relevant &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt;, you prune bad branches early. If a company isn't profitable, Elixir skips iterating over its teams entirely!&lt;/p&gt;

&lt;p&gt;As long as you start the entire comprehension with at least one &lt;code&gt;&amp;lt;generator&amp;gt;, you can mix and match&lt;/code&gt;&lt;code&gt;and&lt;/code&gt;` combinations infinitely!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;to be continued...&lt;/em&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>programming</category>
      <category>webdev</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Is the Internet a Junkyard?</title>
      <dc:creator>Figsy</dc:creator>
      <pubDate>Wed, 08 Oct 2025 21:18:44 +0000</pubDate>
      <link>https://forem.com/figsify/is-the-internet-a-junkyard-540n</link>
      <guid>https://forem.com/figsify/is-the-internet-a-junkyard-540n</guid>
      <description>&lt;p&gt;The internet was once seen as a new frontier for creativity and original ideas. Today, many people describe it differently: as a &lt;strong&gt;junkyard&lt;/strong&gt; or an &lt;strong&gt;echo chamber&lt;/strong&gt;, where the same ideas are repeated over and over. Let's explore the idea that the internet is in a state of decline, constantly recycling its own content, which leads to a &lt;strong&gt;drop in quality and originality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This didn't happen overnight. It's the result of changes in technology and culture over the last 3 decades.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Early Web&lt;/strong&gt; &lt;em&gt;(1990s - early 2000s)&lt;/em&gt;: This was a time of passion projects. People created websites about their hobbies and interests because they wanted to share them with small, like-minded communities. &lt;strong&gt;Originality was natural&lt;/strong&gt; because the web was new and not yet commercialized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Rise of Social Media&lt;/strong&gt; &lt;em&gt;(mid-2000s)&lt;/em&gt;: Platforms like &lt;em&gt;Facebook&lt;/em&gt;, &lt;em&gt;YouTube&lt;/em&gt;, and &lt;em&gt;blogs&lt;/em&gt; made it easy for anyone to create content. But this also meant that a few large companies started to control where and how people shared information. &lt;strong&gt;The goal shifted from personal expression to getting likes, shares, and followers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Age of Google&lt;/strong&gt; &lt;em&gt;(2010s - 2022)&lt;/em&gt;: Getting to the first page of Google search results became the most important goal for many creators. This led to a new way of making content called Search Engine Optimization (SEO). Instead of coming up with new ideas, people began to copy what was already popular, creating slightly different versions of the same articles and lists. We can call this the &lt;strong&gt;"human copy machine"&lt;/strong&gt; 😉 phase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The AI Flood&lt;/strong&gt; &lt;em&gt;(2022 - Today)&lt;/em&gt;: Artificial Intelligence (AI) can now do the job of the "human copy machine" but &lt;strong&gt;thousands of times faster and cheaper&lt;/strong&gt;. This has flooded the internet with AI-generated content, creating a serious problem: &lt;em&gt;AI models are now learning from other AI content, which can cause them to get progressively worse over time&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Characteristic&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Phase I: The Early Web (1990s – early 2000s)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Phase II: The Rise of Social Media (mid-2000s)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Phase III: The Age of Google (2010s – 2022)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Phase IV: The AI Flood (2022 – Today)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Why People Created&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;To share passions and build communities&lt;/td&gt;
&lt;td&gt;To get likes, go viral, and make money&lt;/td&gt;
&lt;td&gt;To rank high on Google and get traffic&lt;/td&gt;
&lt;td&gt;To create content automatically and cheaply&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where People Created&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Personal websites, forums&lt;/td&gt;
&lt;td&gt;Blogs, social media, video sites (like Blogger, Facebook, YouTube)&lt;/td&gt;
&lt;td&gt;Search engines, large content websites&lt;/td&gt;
&lt;td&gt;AI tools like ChatGPT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Creator-Audience Link&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Direct, small, niche groups&lt;/td&gt;
&lt;td&gt;Interactive, community-focused&lt;/td&gt;
&lt;td&gt;Controlled by algorithms, business-like&lt;/td&gt;
&lt;td&gt;Distant, no real relationship&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key Technology&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTML, dial-up internet, early browsers&lt;/td&gt;
&lt;td&gt;Social media platforms, high-speed internet&lt;/td&gt;
&lt;td&gt;Search algorithms, analytics tools&lt;/td&gt;
&lt;td&gt;Artificial Intelligence (AI), Large Language Models (LLMs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Typical Content&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A personal homepage, a fan site, a forum discussion&lt;/td&gt;
&lt;td&gt;A blog post, a viral video, a social media profile&lt;/td&gt;
&lt;td&gt;A “how-to” guide for Google, a list article (“listicle”)&lt;/td&gt;
&lt;td&gt;An AI-written article, an AI summary, a deepfake video&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Internet Starts to Eat Itself (c. 2022-Present)
&lt;/h2&gt;

&lt;p&gt;The current era of Artificial Intelligence (AI), which took off with the release of tools like ChatGPT in late 2022, is the logical conclusion of the previous phase (&lt;em&gt;The Age of Google&lt;/em&gt;). AI models are extremely good at the exact task that SEO taught human writers to do: analyze huge amounts of existing text and create a new summary of it. The only difference is that an AI can do it in seconds, for almost no cost.&lt;/p&gt;

&lt;p&gt;The result has been a massive flood of AI-generated, or "synthetic" content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ahrefs.com/blog/what-percentage-of-new-content-is-ai-generated/" rel="noopener noreferrer"&gt;A 2025 study of 900 thousand new web pages&lt;/a&gt; found that nearly 75% of them had at least some AI-generated content.&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.amazonaws.com%2Fuploads%2Farticles%2Fr6uwpe817onbhqks79aq.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Fr6uwpe817onbhqks79aq.webp" alt="Ahref's study of 900 thousand new web pages" width="800" height="996"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The amount of &lt;a href="https://originality.ai/ai-content-in-google-search-results" rel="noopener noreferrer"&gt;AI content in the top 20 Google search results&lt;/a&gt; has grown dramatically, from around 2% in 2019 to nearly 20% by mid-2025.&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.amazonaws.com%2Fuploads%2Farticles%2Foxiea5arwf8biqtb6hso.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.amazonaws.com%2Fuploads%2Farticles%2Foxiea5arwf8biqtb6hso.png" alt="AI content in the top 20 Google search results" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some experts now believe that &lt;a href="https://www.articlex.com/the-growth-of-generative-ai-insights-from-nina-schick/" rel="noopener noreferrer"&gt;90% of all online content could be generated by AI as early as 2025&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI slop
&lt;/h3&gt;

&lt;p&gt;This flood of AI content is making the internet a less reliable place. The web is being filled with what some call &lt;strong&gt;"AI slop"&lt;/strong&gt;: &lt;em&gt;generic, repetitive, and often boring content that lacks any real human insight or experience.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This has made services like Google search less useful. &lt;a href="https://www.cnet.com/tech/services-and-software/glue-in-pizza-eat-rocks-googles-ai-search-is-mocked-for-bizarre-answers/" rel="noopener noreferrer"&gt;Around mid-2024, reports of several incidents highlighted a growing problem with internet search quality&lt;/a&gt;. Many users expressed frustration that services like Google had become less useful, with search results increasingly cluttered by low-quality, AI-written websites created only for ad revenue.&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.amazonaws.com%2Fuploads%2Farticles%2Fc5wq1cqqyfmk9ld4urnr.jpeg" 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.amazonaws.com%2Fuploads%2Farticles%2Fc5wq1cqqyfmk9ld4urnr.jpeg" alt="how to get cheese to stick to pizza" width="800" height="901"&gt;&lt;/a&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fj5p9kyo8zk4jutmb229j.jpeg" 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.amazonaws.com%2Fuploads%2Farticles%2Fj5p9kyo8zk4jutmb229j.jpeg" alt="you should eat at least one small rock per day" width="800" height="1409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even Google's own AI-powered summaries have given dangerously wrong answers, like telling people to &lt;strong&gt;put glue on pizza&lt;/strong&gt; or &lt;strong&gt;to eat rocks&lt;/strong&gt;. This erodes the trust we have in the internet as a source of good information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Collapse
&lt;/h3&gt;

&lt;p&gt;The biggest long-term threat is a problem called &lt;strong&gt;"model collapse"&lt;/strong&gt;. This is a feedback loop where new AI models are trained on the low-quality AI content created by older models. It's like making a photocopy of a photocopy; each new copy gets blurrier and less clear.&lt;/p&gt;

&lt;p&gt;As AI models learn from other AI-generated text, they start to forget the diversity and richness of real, human-created information. Researchers have found this happens in two stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, the models forget rare or unusual information. They learn the most common patterns, which makes their output very generic.&lt;/li&gt;
&lt;li&gt;As the cycle continues, the models' understanding of the world becomes distorted. Their output becomes a flat, boring copy of a copy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process is polluting the internet's knowledge base. The web, which was the main source of training data for AI, is now being contaminated by AI's own output. This has led some researchers to see all data created before 2022 as a precious, "uncontaminated" resource.&lt;/p&gt;

&lt;p&gt;Some experts still believe the fears of "model collapse" are exaggerated and can be seen as a &lt;strong&gt;"doomsday fear"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.vktr.com/ai-technology/model-collapse-how-generative-ai-is-eating-its-own-data/" rel="noopener noreferrer"&gt;This article&lt;/a&gt; explains that while model collapse (&lt;em&gt;where AI models trained on other AI-generated data lead to a decline in quality&lt;/em&gt;) is a real concern, some experts argue that the most severe predictions are unlikely to happen in the real world. With proper management and a continued emphasis on using high-quality, human-generated data, the most catastrophic outcomes can be avoided.&lt;/p&gt;

&lt;p&gt;The goal of content creation is shifting. It's no longer about informing a human, but about creating a massive amount of content as cheaply as possible to fill up digital space and be seen by search engines. This turns the web into a giant, automated content farm.&lt;/p&gt;

&lt;p&gt;Model collapse is a serious threat. The internet has been our collective memory. If that memory becomes corrupted by endless, degrading copies, we could enter a new kind of digital dark age, where finding true, original knowledge becomes nearly impossible because it's buried under a mountain of synthetic junk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human Creativity in the Age of AI
&lt;/h2&gt;

&lt;p&gt;The rise of AI presents two main challenges to human creativity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Economic Threat&lt;/strong&gt;: For many jobs, like writing marketing copy or making simple graphics, AI can now produce "good enough" content much faster and cheaper than a human. As businesses look to save money, many creative professionals could lose their jobs, which might mean less human creativity overall.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Threat&lt;/strong&gt;:AI could one day become more creative than humans. However, for now, AI has major limitations. AI creativity is just very good pattern-matching. It doesn't come from real understanding or life experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI lacks the key things that make human creativity special, such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI cannot feel joy or sadness, nor can it have the sudden flashes of insight that lead to great art.&lt;/li&gt;
&lt;li&gt;AI doesn't understand culture or social situations in the way humans do.&lt;/li&gt;
&lt;li&gt;AI can only remix what it has learned from its training data. It can't create something completely new from a unique personal vision.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI as a Creative Partner
&lt;/h3&gt;

&lt;p&gt;This leads to a more positive view: AI not as a replacement, but as a powerful assistant that can help humans be more creative.&lt;/p&gt;

&lt;p&gt;In this partnership, AI can do the boring work and spark new ideas.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Do the Boring Work&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;Every creative project has tedious tasks. AI can handle things like basic research, cleaning up audio, or drafting simple text. This frees up human creators to focus on the artistic vision and emotional heart of the work.  &lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Spark New Ideas&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;By mixing ideas in unexpected ways, it can give creators a starting point for something new. For example, Musicians use AI to generate new musical phrases that they then arrange into a finished song that reflects their human vision. Visual artists use tools like DALL-E to quickly test out different ideas and styles. &lt;strong&gt;Humans switch from being creators to curators&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The New Value of Authenticity
&lt;/h3&gt;

&lt;p&gt;In a world flooded with fake and generic AI content, things like &lt;strong&gt;authenticity&lt;/strong&gt;, &lt;strong&gt;real expertise&lt;/strong&gt;, and &lt;strong&gt;genuine human experience&lt;/strong&gt; are becoming more valuable than ever. The content that AI can't create (i.e. &lt;em&gt;personal stories, unique insights from real life, and a distinct point of view&lt;/em&gt;) will be what people seek out and are willing to pay for.&lt;/p&gt;

&lt;p&gt;The internet's content will likely split into two tiers. At the bottom will be a huge amount of cheap, mass-produced AI content. At the top will be a premium level of authentic, human-made content that focuses on originality and emotional connection.&lt;/p&gt;

&lt;p&gt;In this new world, the most important skill for a creator won't just be making things, but having good taste and a strong vision. The successful creator will be someone who can use AI as a powerful assistant to generate ideas, but then use their uniquely human judgment to shape that raw material into something truly meaningful and authentic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Story So Far
&lt;/h3&gt;

&lt;p&gt;The internet is now feeding on itself, risking a future where information quality continues to decline. It has become difficult to tell the difference between something made by a human and something made by a machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  A New Solution?
&lt;/h3&gt;

&lt;p&gt;In this new reality, we need a way to trust what we see online. The first idea was to build AI content detectors, but these are in a constant battle with AI models designed to trick them. A better, more lasting solution is not to just find what's fake, but to prove what's real. This is the idea of content provenance: creating a clear, verifiable record of where a piece of content came from.&lt;/p&gt;

&lt;p&gt;A group of major tech and media companies, including Adobe, Microsoft, and the BBC, have already created an open standard for this, called the Coalition for &lt;a href="https://c2pa.org/" rel="noopener noreferrer"&gt;Content Provenance and Authenticity&lt;/a&gt; (C2PA).&lt;/p&gt;

&lt;p&gt;This system works through something called &lt;strong&gt;Content Credentials&lt;/strong&gt;, which act like a secure &lt;strong&gt;"nutrition label"&lt;/strong&gt; for digital content. &lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;An Example: Here's how C2PA works&lt;/strong&gt;&lt;/u&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a photo is taken or a file is created, the creator can attach Content Credentials. This is a secure piece of information that is cryptographically signed ("label"), so you can tell if it's been tampered with.&lt;/li&gt;
&lt;li&gt;This "label" contains key information, such as who created the content, what tools were used (including if AI was involved), and a history of any changes made to it.&lt;/li&gt;
&lt;li&gt;Companies like Leica, Nikon, and Canon are &lt;a href="https://contentauthenticity.org/how-it-works" rel="noopener noreferrer"&gt;building this technology directly into their cameras&lt;/a&gt;. Software companies like &lt;a href="https://contentauthenticity.adobe.com/" rel="noopener noreferrer"&gt;Adobe are also including it in their tools&lt;/a&gt;, and you will start to see a &lt;strong&gt;"cr"&lt;/strong&gt; icon on content that has these verifiable credentials.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Future of a More Trustworthy Internet
&lt;/h3&gt;

&lt;p&gt;The internet may feel like a junkyard, but we are not without hope. The way forward is to give people the tools to tell the difference between real and fake. Content provenance standards like C2PA do just that. They allow us to ask important questions about the content we see (i.e. who made this? how was it made?) and get trustworthy answers. This helps real human creators prove the authenticity of their work and stand out from the sea of AI-generated media.   &lt;/p&gt;

&lt;p&gt;The future of originality online won't be about banning AI, but about building a new culture of verification. By using these tools, we can move from a world of doubt to one where we can trust what we see, ensuring that even in the junkyard, the real treasures can still be found.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>web</category>
      <category>llm</category>
    </item>
    <item>
      <title>Anatomy of a Supply Chain Heist: The Day 'chalk' and 'debug' Became Crypto-Thieves</title>
      <dc:creator>Figsy</dc:creator>
      <pubDate>Tue, 09 Sep 2025 21:08:23 +0000</pubDate>
      <link>https://forem.com/figsify/anatomy-of-a-supply-chain-heist-the-day-chalk-and-debug-became-crypto-thieves-4fb</link>
      <guid>https://forem.com/figsify/anatomy-of-a-supply-chain-heist-the-day-chalk-and-debug-became-crypto-thieves-4fb</guid>
      <description>&lt;p&gt;Every day, millions of developers type a simple, almost reflexive command into their terminals: &lt;code&gt;npm install&lt;/code&gt;. It’s the foundational act of modern web development, a gateway to a universe of open-source tools that make building complex applications possible. But this routine command, a gesture of implicit trust in a global community, can sometimes open a door to unseen threats. On September 8, 2025, this trust was weaponized in one of the most significant supply chain attacks in recent history, turning ubiquitous, "boring" packages like &lt;code&gt;chalk&lt;/code&gt; and &lt;code&gt;debug&lt;/code&gt; into silent crypto-thieves.&lt;/p&gt;

&lt;p&gt;This incident was not a flaw in the code of these packages but a hijacking of &lt;strong&gt;the trust placed in their maintainer&lt;/strong&gt;. A single, well-crafted &lt;strong&gt;phishing email&lt;/strong&gt; set off a chain reaction that compromised packages with a combined total of over ~two billion weekly downloads, sending shockwaves through the entire JavaScript ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Attack: 🤔 How One Phishing Email Compromised Billions of Downloads?
&lt;/h2&gt;

&lt;p&gt;The effectiveness of this supply chain attack hinged not on a complex zero-day exploit, but on the meticulous exploitation of the most vulnerable part of any security system: &lt;strong&gt;the human element&lt;/strong&gt;. The attackers targeted a single, highly trusted individual to gain a foothold in an ecosystem used by millions.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 The Target: A Respected &lt;a href="https://www.npmjs.com/~qix" rel="noopener noreferrer"&gt;Developer&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The developer at the center of this incident was &lt;a href="https://github.com/Qix-" rel="noopener noreferrer"&gt;&lt;strong&gt;Josh Junon&lt;/strong&gt;&lt;/a&gt;, a prolific and respected open-source contributor known by the handle &lt;code&gt;qix&lt;/code&gt;. With over ~1,800 contributions on GitHub in the past year alone, Junon was the trusted maintainer of dozens of foundational npm packages. These were not obscure libraries; they included utilities like &lt;code&gt;chalk&lt;/code&gt; (for terminal text styling), &lt;code&gt;debug&lt;/code&gt; (a debugging tool), and &lt;code&gt;strip-ansi&lt;/code&gt; (for removing ANSI escape codes), which are transitive dependencies in countless popular frameworks and applications. Combined, the affected packages accounted for a staggering ~2.6 billion weekly downloads, establishing the immense potential blast radius for any compromise.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧲 The Lure
&lt;/h3&gt;

&lt;p&gt;The attack began with a &lt;strong&gt;phishing email&lt;/strong&gt;. The message was sent from the domain &lt;code&gt;support@npmjs.help&lt;/code&gt;, a convincing &lt;strong&gt;lookalike&lt;/strong&gt; of the official &lt;code&gt;npmjs.com&lt;/code&gt; domain. This fraudulent domain &lt;code&gt;npmjs.help&lt;/code&gt; had been registered at &lt;code&gt;porkbun.com&lt;/code&gt; &lt;strong&gt;just three days before the attack&lt;/strong&gt;, a clear sign of a premeditated and targeted operation rather than an opportunistic one.&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.amazonaws.com%2Fuploads%2Farticles%2Fzldp6g30gvknpiwnhekb.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.amazonaws.com%2Fuploads%2Farticles%2Fzldp6g30gvknpiwnhekb.png" alt="Attached is the email Junon shared. The transparency shown here is exemplary and worth recognizing" width="783" height="895"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://gist.github.com/Qix-/c1f0d4f0d359dffaeec48dbfa1d40ee9" rel="noopener noreferrer"&gt;email's content&lt;/a&gt; was a masterclass in psychological manipulation, employing classic social engineering tactics to bypass the recipient's natural caution. It created a sense of urgency and fear, falsely claiming that Junon's account would be locked within 48 hours if he did not update his Two-Factor Authentication (2FA) credentials, which the email alleged were over 12 months old. According to Junon himself, the email looked &lt;a href="https://github.com/debug-js/debug/issues/1005#issuecomment-3267411024" rel="noopener noreferrer"&gt;"very legitimate"&lt;/a&gt;. The attack's success was aided by circumstance; Junon was on his mobile device during a busy week, a common scenario where individuals are more likely to let their guard down. He later candidly acknowledged the compromise on platforms like HackerNews, stating, &lt;a href="https://news.ycombinator.com/item?id=45169794" rel="noopener noreferrer"&gt;"Hi, yep I got pwned... Sorry everyone, very embarrassing"&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🪄 Bypassing 2FA
&lt;/h3&gt;

&lt;p&gt;Crucially, the attack was not a simple credential theft; it was designed to defeat the very 2FA protection that developers are urged to use. The phishing site was not just a static form but an active &lt;a href="https://attack.mitre.org/techniques/T1557/" rel="noopener noreferrer"&gt;Adversary-in-the-Middle (AitM)&lt;/a&gt;, acting as a proxy between the Junon (the victim) and the real npm service. This technique bypasses many common forms of MFA by hijacking the authenticated session itself.&lt;/p&gt;

&lt;p&gt;The process unfolded in real-time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Junon visited the fake site (&lt;code&gt;npmjs.help&lt;/code&gt;) and entered his username and password&lt;/li&gt;
&lt;li&gt;The "AitM" proxy immediately forwarded these credentials to the legitimate &lt;code&gt;npmjs.com&lt;/code&gt; login service.&lt;/li&gt;
&lt;li&gt;The real npm site responded with a challenge for a 2FA token.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npmjs.help&lt;/code&gt; (the fake site) mirrored this prompt, asking Junon for his Time-based One-Time Password (TOTP) code.&lt;/li&gt;
&lt;li&gt;Junon entered the live 2FA code from his authenticator app into the fake site.&lt;/li&gt;
&lt;li&gt;The proxy passed this valid, time-sensitive token to the real npm site, successfully completing the login process.&lt;/li&gt;
&lt;li&gt;The attacker, sitting in the middle, intercepted the resulting session cookie. This token granted them full, authenticated access to Junon's account, rendering his password and 2FA device irrelevant for the duration of the session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method highlights a critical vulnerability in authentication security. While MFA methods like TOTP codes and SMS messages are effective against simple password theft, they are not phishing-resistant. An "AitM" attack doesn't break the cryptography of 2FA; it tricks the user into authenticating on the attacker's behalf. True phishing resistance requires standards like FIDO2/&lt;a href="https://w3c.github.io/webauthn/" rel="noopener noreferrer"&gt;WebAuthn&lt;/a&gt;, which cryptographically bind the authentication process to the specific domain origin, making it impossible for a proxy on a different domain to relay the sign-in attempt.&lt;/p&gt;

&lt;p&gt;Once they had control, the attackers immediately changed the email address associated with the npm account, temporarily locking Junon out and giving them a window to &lt;a href="https://github.com/debug-js/debug/issues/1005#issue-3394266240" rel="noopener noreferrer"&gt;publish their malicious packages&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What exactly is FIDO/WebAuthn?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passwordless authentication is a growing trend in IT security that seeks to replace weak passwords with more secure alternatives, enhancing both user experience and protection.&lt;/li&gt;
&lt;li&gt;At its core is WebAuthn, an API created by the W3C and FIDO Alliance, which allows users to register and authenticate using public key cryptography, generating unique private-public key pairs (credentials) often associated with biometric authenticators like 'Windows Hello" or "Apple’s Touch ID".&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://fidoalliance.org/overview/" rel="noopener noreferrer"&gt;FIDO Alliance&lt;/a&gt; is responsible for developing technical standards for non-password authentication based on public-key cryptography and certifying interoperable solutions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html" rel="noopener noreferrer"&gt;CTAP&lt;/a&gt; (Client to Authenticator Protocol), a specification from the FIDO Alliance, outlines how applications and operating systems interact with authentication devices, with CTAP2 being essential for FIDO2.&lt;/li&gt;
&lt;li&gt;FIDO2 merges WebAuthn and CTAP2 to deliver strong passwordless authentication through devices capable of biometrics or security keys.&lt;/li&gt;
&lt;li&gt;This approach greatly enhances security by employing unique key pairs for each application, relying on inherence (biometrics) and possession (registered device) factors instead of shared secrets, thus &lt;strong&gt;reducing the risks of phishing, stolen credentials, and man-in-the-middle attacks&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Rapid Detection and Response
&lt;/h3&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.amazonaws.com%2Fuploads%2Farticles%2F6zkrx96an57nqkfd1f01.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.amazonaws.com%2Fuploads%2Farticles%2F6zkrx96an57nqkfd1f01.png" alt="Aikido alerted Junon via the social network Bluesky" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite its sophistication, the attack had a very short lifespan thanks to the vigilance of the security community.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;September 8, 2025, ~13:16 UTC&lt;/strong&gt;: The malicious versions of ~18 packages were first published to the npm registry. Security firm &lt;a href="https://www.aikido.dev/" rel="noopener noreferrer"&gt;"Aikido" Security&lt;/a&gt;'s automated intelligence feed flagged the suspicious updates almost immediately and alerted Junon via the social network Bluesky.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;September 8, 2025, ~15:15 UTC&lt;/strong&gt;: Less than two hours after the first malicious publish, Junon had confirmed the compromise and begun the cleanup process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;September 8, 2025, ~17:17 UTC&lt;/strong&gt;: &lt;code&gt;npm&lt;/code&gt; had officially acknowledged the breach and was working to remove the tainted packages from the registry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This rapid, community-driven response was instrumental in containing the damage from what could have been a far more catastrophic incident.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package Name&lt;/th&gt;
&lt;th&gt;Malicious Version&lt;/th&gt;
&lt;th&gt;Approx. Weekly Downloads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ansi-regex&lt;/td&gt;
&lt;td&gt;6.2.1&lt;/td&gt;
&lt;td&gt;~243 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ansi-styles&lt;/td&gt;
&lt;td&gt;6.2.2&lt;/td&gt;
&lt;td&gt;~371 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;backslash&lt;/td&gt;
&lt;td&gt;0.2.1&lt;/td&gt;
&lt;td&gt;~260,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chalk&lt;/td&gt;
&lt;td&gt;5.6.1&lt;/td&gt;
&lt;td&gt;~300 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chalk-template&lt;/td&gt;
&lt;td&gt;1.1.1&lt;/td&gt;
&lt;td&gt;~3.9 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;color&lt;/td&gt;
&lt;td&gt;5.0.1&lt;/td&gt;
&lt;td&gt;~27 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;color-convert&lt;/td&gt;
&lt;td&gt;3.1.1&lt;/td&gt;
&lt;td&gt;~193 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;color-name&lt;/td&gt;
&lt;td&gt;2.0.1&lt;/td&gt;
&lt;td&gt;~191 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;color-string&lt;/td&gt;
&lt;td&gt;2.1.1&lt;/td&gt;
&lt;td&gt;~27 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;debug&lt;/td&gt;
&lt;td&gt;4.4.2&lt;/td&gt;
&lt;td&gt;~357 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;error-ex&lt;/td&gt;
&lt;td&gt;1.3.3&lt;/td&gt;
&lt;td&gt;~47 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;has-ansi&lt;/td&gt;
&lt;td&gt;6.0.1&lt;/td&gt;
&lt;td&gt;~12 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;is-arrayish&lt;/td&gt;
&lt;td&gt;0.3.3&lt;/td&gt;
&lt;td&gt;~73 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;simple-swizzle&lt;/td&gt;
&lt;td&gt;0.2.3&lt;/td&gt;
&lt;td&gt;~26 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slice-ansi&lt;/td&gt;
&lt;td&gt;7.1.1&lt;/td&gt;
&lt;td&gt;~59 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;strip-ansi&lt;/td&gt;
&lt;td&gt;7.1.1&lt;/td&gt;
&lt;td&gt;~261 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;supports-color&lt;/td&gt;
&lt;td&gt;10.2.1&lt;/td&gt;
&lt;td&gt;~287 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;supports-hyperlinks&lt;/td&gt;
&lt;td&gt;4.1.1&lt;/td&gt;
&lt;td&gt;~19 million&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wrap-ansi&lt;/td&gt;
&lt;td&gt;9.0.1&lt;/td&gt;
&lt;td&gt;~198 million&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Weapon: A Deep Dive into the Crypto-Clipper Malware
&lt;/h2&gt;

&lt;p&gt;The payload injected into the compromised packages was a highly specialized piece of malware known as a crypto-clipper. It was designed with a singular purpose: to steal cryptocurrency by intercepting and redirecting transactions in the victim's browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  🥷 What is a Crypto-Clipper? The Digital Pickpocket Analogy
&lt;/h3&gt;

&lt;p&gt;At its core, clipper malware, also known as "cryware" or a "ClipBanker," is a digital thief that exploits the copy-and-paste function. Imagine writing down a friend's bank account number on a slip of paper to make a transfer. As you hand the slip to the bank teller, a pickpocket deftly swaps it with another slip containing their own account number. You complete the transfer, oblivious to the change, and the money goes to the thief.&lt;/p&gt;

&lt;p&gt;A crypto-clipper does this digitally. It silently monitors the device's clipboard, waiting for the user to copy a long, complex cryptocurrency wallet address. When it detects one, it instantly replaces it with an address belonging to the attacker. When the user pastes the address to initiate a transaction, they unknowingly paste the attacker's address, sending their funds into the wrong hands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Under the Hood: Browser Hooking and API Interception
&lt;/h3&gt;

&lt;p&gt;This specific malware was engineered to execute exclusively in a client-side browser environment, meaning it targeted end-users of websites that bundled the malicious packages, not the developers' machines or servers directly. It employed a sophisticated, &lt;strong&gt;two-pronged&lt;/strong&gt; strategy to ensure maximum coverage.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Passive Network Interception&lt;/strong&gt;: The malware began by "hooking," or overriding, the browser's fundamental networking functions (fetch and XMLHttpRequest). This gave it the power to inspect all network traffic flowing in and out of the webpage. &lt;u&gt;When it detected an API response containing a cryptocurrency address&lt;/u&gt;, it would rewrite that address on the fly before the website's legitimate JavaScript code had a chance to process or display it. &lt;a href="https://www.infosecurity-magazine.com/news/npm-supply-chain-attack-averted/" rel="noopener noreferrer"&gt;more...&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Transaction Hijacking&lt;/strong&gt;: The malware's behavior escalated if it detected the presence of a &lt;a href="https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en" rel="noopener noreferrer"&gt;Web3 wallet extension like MetaMask&lt;/a&gt;, which it identified by checking for the &lt;code&gt;window.ethereum&lt;/code&gt; object in the browser. In this mode, it moved from (above mentioned) passive interception to active hijacking. It would intercept API calls made to the wallet, such as &lt;code&gt;eth_sendTransaction&lt;/code&gt;, and directly manipulate the transaction parameters in memory just moments before the user was prompted to sign and approve it. The user would see a legitimate-looking confirmation pop-up from their wallet, but the underlying recipient address had already been maliciously altered. &lt;a href="https://www.upwind.io/feed/npm-supply-chain-attack-massive-compromise-of-debug-chalk-and-16-other-packages" rel="noopener noreferrer"&gt;more...&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This dual-pronged approach was architected to exploit both the technical workings of web applications and the psychological trust a user has in their wallet's interface. By intercepting data at both the network and wallet layers, the malware ensured that even if a user was careful, the information they were verifying had already been compromised. (Holy moly, that's wild 😎)&lt;/p&gt;

&lt;h3&gt;
  
  
  Levenshtein Distance
&lt;/h3&gt;

&lt;p&gt;Perhaps the most clever aspect of the malware was its method for choosing which of the attacker's wallet addresses to use for the swap. Instead of using a single, static address, it employed the Levenshtein distance algorithm.&lt;/p&gt;

&lt;p&gt;This algorithm measures the "edit distance" between two strings - essentially, the minimum number of single-character edits (insertions, deletions, or substitutions) required to change one string into the other. The malware contained a &lt;a href="https://gist.github.com/jdstaerk/f845fbc1babad2b2c5af93916dd7e9fb" rel="noopener noreferrer"&gt;pre-compiled list of attacker-controlled wallets&lt;/a&gt;. When a user copied a legitimate address, the malware would calculate the Levenshtein distance between that address and every address in its list. It would then select the attacker's address that was visually most similar to the original, making the swap incredibly difficult to detect with a cursory glance (without much attention to detail). This technique preys on the fact that cryptocurrency addresses are long and complex, and users rarely verify them character by character.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hiding in Plain Sight: &lt;strong&gt;Code Obfuscation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To avoid immediate detection by developers or security scanners, the malicious code was heavily obfuscated. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code obfuscation is the process of making source code intentionally difficult for humans and automated tools to understand, without altering its functionality.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Common techniques used in such malware include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Symbol Renaming&lt;/strong&gt;: Replacing descriptive variable and function names like &lt;code&gt;replaceWalletAddress&lt;/code&gt; with meaningless single letters like &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;a1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;String Encryption&lt;/strong&gt;: Hiding critical strings, such as wallet addresses or targeted function names, by encoding them in formats like &lt;code&gt;Base64&lt;/code&gt; or &lt;code&gt;hex&lt;/code&gt;, only to be decoded at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control Flow Obfuscation&lt;/strong&gt;: Restructuring the code's logic, turning simple conditional statements into convoluted loops (like &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;) and jumps (like &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, &lt;code&gt;return&lt;/code&gt;, &lt;code&gt;goto&lt;/code&gt;). This creates "spaghetti code" that is &lt;u&gt;functionally identical but logically incomprehensible&lt;/u&gt; to a human analyst.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to embed a small, unreadable block of code into the otherwise legitimate package files, allowing it to slip past all but the most thorough of code reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern: This Has Happened Before, and It Will Happen Again
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;qix&lt;/code&gt; incident, while shocking in its scale, was not an isolated event. It is the latest and most prominent example in an escalating trend of software supply chain attacks targeting the open-source ecosystem. &lt;strong&gt;Attackers have recognized that compromising a single trusted component is a highly efficient way to infect thousands or even millions of downstream users.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The New Perimeter: Why Attackers Love Open Source
&lt;/h3&gt;

&lt;p&gt;A software supply chain attack operates on a simple principle: instead of attacking a fortified castle directly, poison the well that supplies its water. In software, this means injecting malicious code into a trusted upstream dependency (i.e. a library, a framework, or a developer tool) and waiting for that code to be distributed to unsuspecting consumers.&lt;/p&gt;

&lt;p&gt;The npm ecosystem is a particularly fertile ground for these attacks. As the world's largest software registry, it forms the backbone of modern web development. &lt;strong&gt;Projects often have deep and complex dependency trees&lt;/strong&gt;, with hundreds of "transitive dependencies" pulled in automatically without the developer's direct knowledge. This complexity, combined with a culture of implicit trust, creates an environment where a single compromised maintainer account can have a catastrophic ripple effect across the entire industry.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://en.wikipedia.org/wiki/Rogues%27_gallery" rel="noopener noreferrer"&gt;A Rogues' Gallery&lt;/a&gt; of Recent npm Attacks
&lt;/h3&gt;

&lt;p&gt;Analyzing recent major npm compromises reveals a clear pattern of evolving attacker sophistication. They are moving from broad, opportunistic attacks to highly strategic operations with payloads tailored to the specific context of the compromised package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ua-parser-js&lt;/code&gt; (October 2021)&lt;/strong&gt;: In a similar account hijacking incident, an attacker gained control of the &lt;code&gt;ua-parser-js&lt;/code&gt; package, which boasts millions of weekly downloads. They published malicious versions designed to install a Monero cryptocurrency miner on infected machines and deploy the DANABOT banking trojan on Windows systems.  &lt;a href="https://cloud.google.com/blog/topics/threat-intelligence/supply-chain-node-js/" rel="noopener noreferrer"&gt;This attack&lt;/a&gt; demonstrated a similar entry vector (account compromise) but with a more generic, resource-hijacking payload. &lt;a href="https://cloud.google.com/blog/topics/threat-intelligence/supply-chain-node-js/" rel="noopener noreferrer"&gt;more...&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;eslint-config-prettier&lt;/code&gt; &amp;amp; &lt;code&gt;is&lt;/code&gt; package (July 2025)&lt;/strong&gt;: These compromises were part of a sustained phishing campaign that used typosquatted domains (like &lt;code&gt;npnjs.com&lt;/code&gt; - &lt;code&gt;n&lt;/code&gt; instead of &lt;code&gt;m&lt;/code&gt;) and clever social engineering to harvest maintainer credentials. The attack on the &lt;code&gt;is&lt;/code&gt; package was particularly insidious, as the attackers phished an old maintainer and then tricked the current maintainer into re-granting them publishing rights, exploiting the trust between developers. &lt;a href="https://www.stepsecurity.io/blog/another-npm-supply-chain-attack-the-is-package-compromise" rel="noopener noreferrer"&gt;more...&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;nx&lt;/code&gt; Compromise (August 2025)&lt;/strong&gt;: This attack marked a significant leap in sophistication. After a maintainer's npm token was leaked, attackers published malicious versions of the popular &lt;code&gt;nx&lt;/code&gt; build system. The payload was not generic; it was a highly targeted credential harvester designed to steal secrets directly from the developer's environment, including SSH keys, &lt;code&gt;.npmrc&lt;/code&gt; files, cloud credentials, and GitHub tokens. &lt;a href="https://www.aikido.dev/blog/popular-nx-packages-compromised-on-npm" rel="noopener noreferrer"&gt;more...&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This evolution shows that attackers are no longer just dropping malware; they are strategically analyzing their targets. When they compromise a front-end utility like &lt;code&gt;chalk&lt;/code&gt;, they deploy a browser-based payload. When they compromise a developer tool like &lt;code&gt;nx&lt;/code&gt;, they deploy a payload designed to steal developer credentials, which can then be used to launch even more supply chain attacks. This strategic tailoring of the weapon to the target represents a dangerous new phase in the security of the open-source supply chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  True Costs and the Lingering Threat in Your Nexus Cache
&lt;/h2&gt;

&lt;p&gt;The real impact of a supply chain attack is rarely measured by the attacker's direct financial gain. Instead, it is measured in the disruption, cost, and erosion of trust inflicted upon the entire ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pennies Stolen, Millions Wasted
&lt;/h3&gt;

&lt;p&gt;Despite the attack's enormous reach, the amount of cryptocurrency successfully stolen was surprisingly minuscule. Reports indicate the primary attacker wallet received only about 5 cents worth of ETH and $20 of a memecoin. This paltry sum stands in stark contrast to the true cost of the incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;The real damage&lt;/u&gt;&lt;/strong&gt; was a massive, industry-wide "denial-of-service" attack on productivity. Thousands of engineering and security teams across the globe were forced to drop everything, spending countless hours investigating their exposure, auditing their dependency trees, purging potentially contaminated systems, and reassuring stakeholders. This collective loss of productivity represents the true, multi-million-dollar financial impact of the attack.&lt;/p&gt;

&lt;p&gt;Furthermore, incidents like this inflict long-term damage on the trust that underpins the open-source model. Every &lt;code&gt;npm install&lt;/code&gt; now carries a small but palpable risk, forcing developers and organizations to adopt more defensive, time-consuming, and cautious development practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Sonatype Nexus Amplifies the Threat
&lt;/h3&gt;

&lt;p&gt;For many organizations, the threat did not disappear when npm removed the malicious packages from the public registry. Companies that use a local repository manager like "Sonatype Nexus" faced a hidden, persistent danger. A repository manager acts as a private, local cache for external dependencies. When a developer or a CI/CD pipeline requests a package, Nexus checks its local storage. If the package isn't there, Nexus fetches it from the public registry (like npmjs.com), stores a copy for future use, and then serves it to the requester. This process is designed to improve build speed, ensure dependency availability during public registry outages, and provide a central point for security scanning. &lt;/p&gt;

&lt;p&gt;However, this very mechanism for resilience becomes a critical vulnerability during a supply chain attack. The sequence of events is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;During the two-hour window when the malicious packages were live, an internal build requests a compromised version, for example, &lt;code&gt;chalk@5.6.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Nexus, not having this version cached, downloads it from the public npm registry and stores it in its local "blob store."&lt;/li&gt;
&lt;li&gt;Nexus serves the poisoned package to the internal build, potentially compromising the resulting application.&lt;/li&gt;
&lt;li&gt;The npm security team acts swiftly and removes &lt;code&gt;chalk@5.6.1&lt;/code&gt; from the public registry.&lt;/li&gt;
&lt;li&gt;The Problem Persists: &lt;strong&gt;The malicious package still exists within the company's private Nexus cache&lt;/strong&gt;. From this point forward, every internal developer and every CI/CD build that requests that specific version will be served the poisoned copy directly from Nexus, which no longer checks the public registry for a package it has already cached.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this scenario, a tool designed to enhance security and reliability becomes a persistent internal vector for the malware, amplifying and prolonging the attack's window of exposure long after the public threat has been neutralized. Infrastructure designed for operational resilience can inadvertently create significant security blind spots, demonstrating a fundamental tension between the DevOps goals of speed and reliability and the security imperative of continuous verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Step-by-Step Guide to Recovery and Resilience
&lt;/h2&gt;

&lt;p&gt;Recovering from a supply chain attack requires a coordinated effort. The following steps are divided into three parts: immediate triage for individual developers, a guide for purging contaminated infrastructure like Nexus, and long-term strategies to harden defenses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part A: Immediate Triage for Your Projects (For Every Developer)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Audit Your Dependencies
&lt;/h4&gt;

&lt;p&gt;Run &lt;code&gt;npm audit&lt;/code&gt; in the root of every project. This command checks the project's dependency tree against the npm advisory database for known vulnerabilities and will flag the malicious versions of the compromised packages.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Manually Inspect Your Lockfiles (beyond &lt;code&gt;npm ls&lt;/code&gt;, &lt;code&gt;npm explain&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Do not rely on &lt;code&gt;npm audit&lt;/code&gt; alone. Manually search the &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt; file for any of the compromised packages and versions listed in the table earlier in this report. This provides definitive proof of whether a malicious version was ever installed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Search for Indicators of Compromise (IoCs)
&lt;/h4&gt;

&lt;p&gt;If a malicious package was used in a front-end build, the malware's code may be present in the final bundled JavaScript files. Use a command-line tool like grep or your code editor's search function to scan the built application code for the following specific strings and patterns, which are known IoCs for this malware&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global variables: &lt;code&gt;stealthProxyControl&lt;/code&gt;, &lt;code&gt;runmask&lt;/code&gt;, &lt;code&gt;newdlocal&lt;/code&gt;, &lt;code&gt;checkethereumw&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attacker's Ethereum address: &lt;code&gt;0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 4: Perform a Clean Reinstall
&lt;/h4&gt;

&lt;p&gt;To ensure the environment is completely clean, perform a full reinstallation of dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete the &lt;code&gt;node_modules&lt;/code&gt; directory and the project's lockfile (&lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;package.json&lt;/code&gt; file, ensure dependencies are pinned to known safe versions (i.e., versions published before the incident)&lt;/li&gt;
&lt;li&gt;Clear the local npm cache to remove any tainted packages stored on the machine by running &lt;code&gt;npm cache clean --force&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm install&lt;/code&gt; to generate a new, clean lockfile and install dependencies from a safe state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Part B: Purging the Poison from Your Nexus Repository (For System Administrators)
&lt;/h3&gt;

&lt;p&gt;Removing the malicious packages from the central Nexus cache is critical to prevent reinfection across the organization.&lt;/p&gt;

&lt;h4&gt;
  
  
  Option 1: The Surgical Approach (Component Deletion)
&lt;/h4&gt;

&lt;p&gt;Use the search feature in the Nexus Repository UI to locate the specific malicious components by name and version (e.g., repository: &lt;code&gt;npm-proxy&lt;/code&gt;, name: &lt;code&gt;chalk&lt;/code&gt;, version: &lt;code&gt;5.6.1&lt;/code&gt;). Alternatively, use the Nexus REST API to script this search. Once located, use the "Delete component" button in the UI to remove it. This can also be done programmatically.&lt;/p&gt;

&lt;h4&gt;
  
  
  Option 2: The Aggressive Approach (Cleanup Policies)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to Administration -&amp;gt; Repository -&amp;gt; Cleanup Policies and create a new policy. Set an aggressive criterion, such as "Component Usage," to remove components that were "Last downloaded before 1 day(s)"&lt;/li&gt;
&lt;li&gt;Edit the configuration of the affected repository (i.e. &lt;code&gt;npm-proxy&lt;/code&gt;) and assign this new cleanup policy to it.&lt;/li&gt;
&lt;li&gt;Manually execute the &lt;strong&gt;"Admin -&amp;gt; Cleanup repositories using their associated policies"&lt;/strong&gt; task from the System -&amp;gt; Tasks menu to trigger the purge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Mandatory Final Step: Compact the Blob Store
&lt;/h4&gt;

&lt;p&gt;Both of the above methods only "soft delete" the components; the data still resides on the disk and the space is not reclaimed. To permanently remove the data, an administrator &lt;strong&gt;must&lt;/strong&gt; run the &lt;strong&gt;"Admin -&amp;gt; Compact blob store"&lt;/strong&gt; task for the relevant blob store. This is a critical and often-overlooked final step to ensure the malicious artifact is truly gone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part C: Hardening Your Defenses for the Future
&lt;/h3&gt;

&lt;p&gt;Preventing the next attack requires adopting more resilient practices at both the developer and organizational levels.&lt;/p&gt;

&lt;h4&gt;
  
  
  For Developers:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enforce Lockfiles&lt;/strong&gt;: Always commit &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt; to source control. In CI/CD environments, use &lt;code&gt;npm ci&lt;/code&gt; instead of &lt;code&gt;npm install&lt;/code&gt;. The &lt;code&gt;ci&lt;/code&gt; command performs a clean install based only on the lockfile, ensuring deterministic and repeatable builds that are not susceptible to newly published malicious versions.   &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harden Your Accounts&lt;/strong&gt;: Enable 2FA on all developer accounts, especially for package registries (npm) and source control (GitHub). More importantly, advocate for and adopt phishing-resistant MFA methods like &lt;code&gt;FIDO2/WebAuthn&lt;/code&gt; security keys, which are immune to the "AitM" attack that caused this incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  For Organizations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automate Security in CI/CD&lt;/strong&gt;: Integrate dependency scanning directly into the CI/CD pipeline. Configure &lt;code&gt;npm audit&lt;/code&gt; to run on every build and set a failure threshold (e.g., &lt;code&gt;--audit-level=high&lt;/code&gt;) to automatically block code with critical vulnerabilities from being deployed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage the Proxy&lt;/strong&gt;: Continue using a local proxy like Nexus, but incorporate the purging procedures from &lt;strong&gt;Part B&lt;/strong&gt; into the official incident response plan. Consider investing in tools like &lt;strong&gt;Sonatype Repository Firewall&lt;/strong&gt;, which can automatically identify and block malicious packages from entering the cache in the first place, shifting from a reactive to a proactive defense.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately, recovery from a supply chain attack is a shared responsibility. Developers must secure their local environments and codebases, while operations and security teams must secure the shared infrastructure. A clean &lt;code&gt;node_modules&lt;/code&gt; folder is of little use if the CI server pulls the same poison from a contaminated Nexus cache, and a pristine Nexus cache cannot protect a developer whose lockfile is already pointing to a malicious version. A coordinated, multi-layered response is the only effective path to resilience.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Price of Trust
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;qix&lt;/code&gt; incident serves as a powerful reminder of the fragile nature of trust in the digital supply chain. It demonstrated how sophisticated phishing can bypass standard security controls, how clever malware can exploit both technical and psychological vulnerabilities, and how infrastructure designed for efficiency can become a vector for persistent threats. &lt;strong&gt;The open-source ecosystem is built on a foundation of trust&lt;/strong&gt;, but this event makes it clear that &lt;strong&gt;trust must now be paired with rigorous verification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The true impact was not the theft of cryptocurrency but the &lt;strong&gt;theft of time, productivity, and confidence&lt;/strong&gt;. Yet, the story also contains a lesson of empowerment. The rapid response from the security community, the transparency of the compromised developer, and the collective effort to remediate the issue highlight the ecosystem's resilience.&lt;/p&gt;

&lt;p&gt;By understanding these attacks, adopting defensive coding practices, and advocating for stronger security measures, developers (even junior ones) are not helpless. They are the essential guardians on the front lines of the software supply chain.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>javascript</category>
      <category>security</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>V8, the engine behind Chrome &amp; Node.js, just made JSON.stringify more than twice as fast! This is a huge win for web performance.</title>
      <dc:creator>Figsy</dc:creator>
      <pubDate>Sun, 17 Aug 2025 14:42:19 +0000</pubDate>
      <link>https://forem.com/figsify/v8-the-engine-behind-chrome-nodejs-just-made-jsonstringify-more-than-twice-as-fast-this-is-a-46bp</link>
      <guid>https://forem.com/figsify/v8-the-engine-behind-chrome-nodejs-just-made-jsonstringify-more-than-twice-as-fast-this-is-a-46bp</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9" class="crayons-story__hidden-navigation-link"&gt;The Invisible Optimization That Sped Up the Web: How V8 Supercharged JSON.stringify&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/figsify" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2175536%2Fc8805edf-716f-4a35-a631-8d86c91f093f.jpg" alt="figsify profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/figsify" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Figsy
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Figsy
                
              
              &lt;div id="story-author-preview-content-2778294" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/figsify" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2175536%2Fc8805edf-716f-4a35-a631-8d86c91f093f.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Figsy&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 17 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9" id="article-link-2778294"&gt;
          The Invisible Optimization That Sped Up the Web: How V8 Supercharged JSON.stringify
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/node"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;node&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/v8"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;v8&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/jsonstringify"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;jsonstringify&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            18 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>node</category>
      <category>javascript</category>
      <category>v8</category>
      <category>jsonstringify</category>
    </item>
    <item>
      <title>The Invisible Optimization That Sped Up the Web: How V8 Supercharged JSON.stringify</title>
      <dc:creator>Figsy</dc:creator>
      <pubDate>Sun, 17 Aug 2025 14:17:24 +0000</pubDate>
      <link>https://forem.com/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9</link>
      <guid>https://forem.com/figsify/the-invisible-optimization-that-sped-up-the-web-how-v8-supercharged-jsonstringify-ke9</guid>
      <description>&lt;p&gt;If you've ever built a web application, especially one with a backend (like a server written in Node.js), you've almost certainly used &lt;code&gt;JSON.stringify&lt;/code&gt;. It's the go-to tool for turning structured data (like a list of users or products) into a plain text format that can be sent over the internet as part of an API response, or saved in your browser's local storage.&lt;/p&gt;

&lt;p&gt;Well, the JavaScript engine called V8 (which powers popular browsers like Chrome and Node.js) has made &lt;code&gt;JSON.stringify&lt;/code&gt; more than twice as fast! This is a huge deal, meaning quicker page interactions and more responsive applications for all of us.&lt;/p&gt;

&lt;p&gt;This was not an optimization in search of a problem. For years, developers in the Node.js community have identified &lt;code&gt;JSON.stringify&lt;/code&gt; as a critical performance chokepoint. In community discussions, it has been described as one of the "biggest impediments to just about everything around performant node services". Given that Node.js operates on a single-threaded event loop, a CPU-intensive, blocking operation like serializing a large JSON object can halt the entire server, preventing it from handling other requests. This makes the function's performance a direct factor in a server's scalability and throughput.&lt;/p&gt;

&lt;p&gt;The V8 team's work, therefore, addresses a well-known and systemic pain point, directly enabling developers to build more efficient and scalable backend systems. Let's dive into how they pulled this off, with some simple examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does  Actually Do?
&lt;/h2&gt;

&lt;p&gt;Imagine you have some information organized neatly in your JavaScript code, like a profile for a person.&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;userProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;JSON.stringify&lt;/code&gt; takes this structured data and converts it into a plain string of text that can be easily sent over a network or stored.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JSON.stringify converts it to a string:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// This is the output of JSON.stringify&lt;span class="o"&gt;(&lt;/span&gt;userProfile&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="s1"&gt;'{"id":123,"name":"Jane Doe","isActive":true,"roles":["admin","editor"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll often see this when an API sends back a list of items, like an array of these kinds of objects with the same structure, which is a very common scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Improvements and How They Work
&lt;/h2&gt;

&lt;p&gt;The engineers at V8 re-thought &lt;code&gt;JSON.stringify&lt;/code&gt; from the ground up, focusing on core operations like memory management and character handling&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Super Highway" for Clean Data (Side-Effect-Free Fast Path)
&lt;/h3&gt;

&lt;p&gt;Think of it like shipping a package. If your package is simple, contains only standard items, and doesn't require any custom processing or special instructions, it can go on a super-fast, automated conveyor belt.&lt;/p&gt;

&lt;p&gt;V8 now has a special &lt;strong&gt;fast path&lt;/strong&gt; for data that's &lt;strong&gt;plain&lt;/strong&gt; and &lt;strong&gt;clean&lt;/strong&gt;. This means the &lt;strong&gt;data&lt;/strong&gt; doesn't involve any hidden code running or complex internal operations that could cause &lt;strong&gt;side effects&lt;/strong&gt; when it's being converted to JSON.&lt;/p&gt;

&lt;p&gt;Most typical data we send, especially in API responses, falls into this "clean" category. This allows V8 to &lt;strong&gt;bypass many expensive checks and defensive logic&lt;/strong&gt; that the older, more general serializer had to perform, leading to a significant speedup for common JavaScript objects.&lt;/p&gt;

&lt;p&gt;To stay on the &lt;strong&gt;fast path&lt;/strong&gt;, the data being serialized must be "&lt;strong&gt;plain&lt;/strong&gt;". This means it cannot contain features that would force the engine to execute arbitrary code during the serialization process.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Consider the following examples:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean Object (Eligible for the Fast Path):&lt;/strong&gt;&lt;br&gt;
This object is a simple container for data. It has no hidden logic.&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;userProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev_user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;javascript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;performance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// V8 can safely assume serializing this object has no side effects.&lt;/span&gt;
&lt;span class="c1"&gt;// It will use the ultra-fast "Super Highway."&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;userProfile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Object with Side Effects (Forced onto the Slower, General Path):&lt;/strong&gt;&lt;br&gt;
This object contains custom logic that gets triggered during serialization, creating side effects.&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;userProfileWithSideEffects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev_user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// A custom.toJSON method is user-defined code. V8 must execute it.&lt;/span&gt;
  &lt;span class="na"&gt;toJSON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Custom.toJSON() method was called!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// A clear side effect (I/O)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// When V8 sees the.toJSON() method, it cannot make assumptions.&lt;/span&gt;
&lt;span class="c1"&gt;// It must fall back to the slower, general-purpose serializer to execute the function safely.&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;userProfileWithSideEffects&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other features that cause a fallback include using a &lt;code&gt;replacer&lt;/code&gt; function or encountering a &lt;code&gt;Proxy&lt;/code&gt; object, as both involve executing user code that V8 cannot predict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;replacer&lt;/code&gt; function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;replacer&lt;/code&gt; is a function passed as the second argument to &lt;code&gt;JSON.stringify&lt;/code&gt;. It gets called for every key-value pair in the object being serialized, giving you a chance to modify or skip values on the fly. Since this involves running arbitrary user-defined code for each property, V8 can't predict the outcome and must opt out of its "fast path".&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Consider the following example:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have user data but you don't want to expose the user's &lt;code&gt;email&lt;/code&gt; and you want to format their &lt;code&gt;lastLogin&lt;/code&gt; date for the output.&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;// The data object&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jdoe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john.doe@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-08-17T08:30:00Z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// The replacer function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;replacer&lt;/span&gt; &lt;span class="o"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Skip the 'email' property&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&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="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Returning undefined removes the property&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Format the 'lastLogin' date&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&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="s2"&gt;lastLogin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// V8 can't know this logic ahead of time&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Return the original value for all other keys&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Using JSON.stringify with the replacer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userJson&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;replacer&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="c1"&gt;// The '2' is for pretty-printing&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": 42,
  "username": "jdoe",
  "lastLogin": "8/17/2025, 8:30:00 AM",
  "roles": [
    "editor",
    "viewer"
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;V8 cannot optimize this process because it has to pause and execute the &lt;code&gt;replacer&lt;/code&gt; function for every single property (&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, etc.). It's impossible to know in advance that you'll be filtering the &lt;code&gt;email&lt;/code&gt; or reformatting the &lt;code&gt;lastLogin&lt;/code&gt; date. This unpredictability forces a retreat to the slower, more cautious serialization method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;Proxy&lt;/code&gt; Object&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;Proxy&lt;/code&gt; is an object that wraps another object and intercepts fundamental operations, such as getting or setting a property. When &lt;code&gt;JSON.stringify&lt;/code&gt; tries to access the properties of a Proxy, it's not directly reading the data; it's triggering user-defined "trap" functions (get, has, etc.). This is another form of unpredictable user code that V8's fast path cannot handle.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Consider the following example:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's create a proxy that logs every time a property is accessed and hides any property that starts with an underscore (_).&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;// The original data object, with a "private" property&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secret_agent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;_missionCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alpha-7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// This should not be serialized&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// The handler with the trap logic for the Proxy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This 'get' trap is called whenever a property is read&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Intercepted: Getting property "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;property&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;span class="c1"&gt;// Hide properties starting with '_'&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// This 'ownKeys' trap is needed for JSON.stringify to know which keys exist&lt;/span&gt;
  &lt;span class="na"&gt;ownKeys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Intercepted: Getting all keys&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Create the proxy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyUser&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;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Try to stringify the proxy&lt;/span&gt;
&lt;span class="c1"&gt;// JSON.stringify will trigger the 'get' and 'ownKeys' traps&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyJson&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;proxyUser&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;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Final JSON output:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intercepted: Getting all keys
Intercepted: Getting property "id"
Intercepted: Getting property "username"

Final JSON output:
{
  "id": 101,
  "username": "secret_agent"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;JSON.stringify&lt;/code&gt; processes &lt;code&gt;proxyUser&lt;/code&gt;, it doesn't just read &lt;code&gt;{ id: 101, ... }&lt;/code&gt;. Instead, for every property it wants to read, it must execute the logic inside the &lt;code&gt;handler.get&lt;/code&gt; and &lt;code&gt;handler.ownKeys&lt;/code&gt; traps. The behavior of these traps is completely unpredictable - they could return anything, perform calculations, or even throw errors. V8 cannot make any safe assumptions and must use the "slow path" that correctly invokes the proxy's logic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Iteration over Recursion
&lt;/h4&gt;

&lt;p&gt;A subtle but critical architectural improvement within the new "fast path" is that it is &lt;strong&gt;iterative&lt;/strong&gt;, not &lt;strong&gt;recursive&lt;/strong&gt;. A traditional approach to traversing a nested object structure often uses &lt;strong&gt;recursion&lt;/strong&gt;, where a function calls itself to process each level of nesting. However, this can lead to a "Maximum call stack size exceeded" error if the object is too deep.   &lt;/p&gt;

&lt;p&gt;The new iterative design completely sidesteps this problem. It "eliminates the need for stack overflow checks" and allows for the serialization of "significantly deeper nested object graphs". This means the optimization is not just about raw speed; it also enhances the robustness and capability of &lt;code&gt;JSON.stringify&lt;/code&gt;, allowing it to handle larger and more complex data structures without crashing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Consider the following example:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The JavaScript code examples below demonstrate the conceptual difference between a &lt;strong&gt;recursive&lt;/strong&gt; and an &lt;strong&gt;iterative&lt;/strong&gt; approach to traversing an object. The actual high-performance implementation of this iterative logic is handled deep inside the V8 engine's C++ source code. The examples are provided for illustrative purposes to help developers visualize the robust, non-blocking strategy that V8 now uses internally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traversing a Nested Object&lt;/strong&gt;&lt;br&gt;
Let's use a common task for &lt;code&gt;JSON.stringify&lt;/code&gt;: traversing a nested object to read all its values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Recursive Way&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this approach, the &lt;code&gt;traverse&lt;/code&gt; function calls itself for every nested object it finds.&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;userProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;traverseRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Found key: &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="s2"&gt;, value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// If the value is another object, call the same function on it&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&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="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;obj&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="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;traverseRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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="c1"&gt;// &amp;lt;&amp;lt;&amp;lt; RECURSIVE CALL&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--- Recursive Traversal ---&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;traverseRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userProfile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it works?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;traverseRecursively&lt;/code&gt; is called on userProfile.&lt;/li&gt;
&lt;li&gt;It processes &lt;code&gt;name&lt;/code&gt; and then &lt;code&gt;settings&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When it sees &lt;code&gt;settings&lt;/code&gt; is an object, it pauses and calls &lt;code&gt;traverseRecursively&lt;/code&gt; on the &lt;code&gt;settings&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;That second call processes &lt;code&gt;theme&lt;/code&gt; and &lt;code&gt;notifications&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When it sees &lt;code&gt;notifications&lt;/code&gt; is an object, it pauses and calls &lt;code&gt;traverseRecursively&lt;/code&gt; a third time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the Danger?&lt;/p&gt;

&lt;p&gt;Each function call is added to the &lt;strong&gt;call stack&lt;/strong&gt;. If the object were 20,000 levels deep, you would have 20,000 function calls waiting on the &lt;strong&gt;stack&lt;/strong&gt;, leading to a crash.&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;// A deeply nested object that will cause a stack overflow&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This will likely throw: "Maximum call stack size exceeded"&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;traverseRecursively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. The Iterative Way&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This version uses a simple &lt;code&gt;while&lt;/code&gt; loop and an array (&lt;code&gt;nodesToVisit&lt;/code&gt;) that acts as our to-do list, completely avoiding deep function calls.&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;userProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;traverseIteratively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Our "to-do list" starts with the main object&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nodesToVisit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c1"&gt;// Loop as long as there are objects to process&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nodesToVisit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&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;currentNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodesToVisit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Get the next object to work on&lt;/span&gt;

    &lt;span class="k"&gt;for &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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;currentNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Found key: &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="s2"&gt;, value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentNode&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// If a value is another object, add it to our to-do list&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;currentNode&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="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;currentNode&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="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;nodesToVisit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentNode&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="c1"&gt;// &amp;lt;&amp;lt;&amp;lt; NO RECURSIVE CALL&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;--- Iterative Traversal ---&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;traverseIteratively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userProfile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it works?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;nodesToVisit&lt;/code&gt; array starts with just &lt;code&gt;[userProfile]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;while&lt;/code&gt; loop starts. It takes &lt;code&gt;userProfile&lt;/code&gt; out of the array.&lt;/li&gt;
&lt;li&gt;It processes &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;settings&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When it finds the &lt;code&gt;settings&lt;/code&gt; object, it just adds it to the &lt;code&gt;nodesToVisit&lt;/code&gt; array. The array is now &lt;code&gt;[settings object]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On the next loop, it takes &lt;code&gt;settings&lt;/code&gt; out, processes its keys, and adds the &lt;code&gt;notifications&lt;/code&gt; object to the array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the Benefit?&lt;/p&gt;

&lt;p&gt;This version can handle the deeply nested object without any problems.&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;let&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This works perfectly, no crash!&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;--- Iterative on Deep Object ---&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// We won't print every line, but we can confirm it runs.&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;traverseIteratively&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Successfully traversed deep object iteratively!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This should not happen:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By switching &lt;code&gt;JSON.stringify&lt;/code&gt; from a &lt;strong&gt;recursive&lt;/strong&gt; to an &lt;strong&gt;iterative&lt;/strong&gt; internal design, V8 made it more robust. It's not just faster for common cases; it's now capable of handling extremely deep, complex objects without the risk of crashing from a "Maximum call stack size exceeded" error. This makes it a more reliable tool for heavy-duty data serialization.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The "Express Lane" for Similar Data (A huge win for API responses!)
&lt;/h3&gt;

&lt;p&gt;Within the main "Super Highway," V8 introduced an even faster "Express Lane." This optimization provides a massive speed boost for one of the most common use cases on the web: serializing an array of objects that all have the same structure, such as a list of products or users returned from an API. To understand how this works, one must first understand a core concept of V8's internal design: &lt;strong&gt;Hidden Classes&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  A Primer on V8's Hidden Classes
&lt;/h4&gt;

&lt;p&gt;JavaScript is a dynamically typed language, meaning you can add or remove properties from an object at any time. While flexible, this poses a performance challenge. If objects are treated like simple dictionaries, accessing a property like &lt;code&gt;user.email&lt;/code&gt; would require a slow string-based lookup to find the memory location of that property's value.&lt;/p&gt;

&lt;p&gt;To solve this, V8 uses a mechanism called &lt;strong&gt;Hidden Classes&lt;/strong&gt; (also known internally as &lt;strong&gt;Maps&lt;/strong&gt;). When an object is created, V8 creates a hidden class that acts as an internal blueprint, describing the object's "shape" - its properties and the order they were added in. When another object is created with the exact same shape, V8 can reuse the same hidden class. This allows the engine to treat the object's properties as if they had a fixed layout, similar to statically typed languages like Java. Instead of a slow dictionary lookup, V8 knows the exact memory offset for each property, enabling incredibly fast access.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;What might have happened without this (Hidden Classes) optimization?&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;At its core, a basic JavaScript object is like a dictionary or a hash map. It's a collection of key-value pairs. When you write &lt;code&gt;user.email&lt;/code&gt;, you're telling the engine to find the value associated with the key &lt;code&gt;"email"&lt;/code&gt; inside the &lt;code&gt;user&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Without optimizations, the engine would have to perform a string-based lookup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get the key&lt;/strong&gt;: The engine takes the string &lt;code&gt;"email"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash the key&lt;/strong&gt;: It might run the string through a hashing function to get a unique identifier, like &lt;code&gt;48291&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find the key in memory&lt;/strong&gt;: It then has to search through the object's internal list of properties to find a match for the string &lt;code&gt;"email"&lt;/code&gt; (or its hash).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieve the value's location&lt;/strong&gt;: Once it finds the matching key, it gets the memory address where the actual value (&lt;code&gt;"jane.doe@example.com"&lt;/code&gt;) is stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return the value&lt;/strong&gt;: Finally, it fetches the data from that memory address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process, especially the "find the key" step, is computationally expensive. It has to be repeated every single time you access &lt;code&gt;user.email&lt;/code&gt;, even inside a tight loop running thousands of times. For a dynamic language, this is the default, safe way to do things, but it's not fast.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;How Hidden Classes (Shapes) solves this problem?&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;The engineers behind V8 realized that in most real-world applications, developers create many objects with the &lt;strong&gt;exact same structure&lt;/strong&gt; (same properties in the same order). V8 leverages this pattern to avoid the slow string lookups.&lt;/p&gt;

&lt;p&gt;It does this using a concept called Hidden Classes (also known as Shapes or Maps).&lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Creating a Hidden Class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you create an object, V8 creates a &lt;strong&gt;Hidden Class&lt;/strong&gt; behind the scenes. This acts as a blueprint for that object's shape.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;JS Code&lt;/th&gt;
&lt;th&gt;V8's action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;const user1 = {};&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a blank Hidden Class, let's call it &lt;code&gt;C0&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;user1.name = "Jane";&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a new Hidden Class &lt;code&gt;C1&lt;/code&gt; based on &lt;code&gt;C0&lt;/code&gt;. &lt;code&gt;C1&lt;/code&gt; describes an object that has a single property, &lt;code&gt;name&lt;/code&gt;. V8 also &lt;u&gt;records the memory offset&lt;/u&gt; for &lt;code&gt;name&lt;/code&gt;. For example, it knows &lt;code&gt;name&lt;/code&gt; is stored right at the beginning of the object's memory block (offset: 0).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;user1.email = "jane.doe@example.com";&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates another Hidden Class &lt;code&gt;C2&lt;/code&gt; based on &lt;code&gt;C1&lt;/code&gt;. &lt;code&gt;C2&lt;/code&gt; describes an object with properties &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt;. V8 records that &lt;code&gt;email&lt;/code&gt; is stored at the next memory location (e.g., offset: 1).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;user1&lt;/code&gt; object is now tagged with Hidden Class &lt;code&gt;C2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Reusing the Hidden Class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, here comes the magic. When you create a second object with the same properties in the same order:&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;user2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nx"&gt;user2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;user2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john.smith@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;V8 follows the exact same steps. It sees you're creating an object with the same "shape" as &lt;code&gt;user1&lt;/code&gt;. Instead of creating new Hidden Classes, it simply tags &lt;code&gt;user2&lt;/code&gt; with the existing Hidden Class &lt;code&gt;C2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: The High-Speed Access&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, when your code runs &lt;code&gt;console.log(user1.email)&lt;/code&gt; or &lt;code&gt;console.log(user2.email)&lt;/code&gt;, V8 performs a much faster, direct memory access:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check Hidden Class&lt;/strong&gt;: V8 sees that both &lt;code&gt;user1&lt;/code&gt; and &lt;code&gt;user2&lt;/code&gt; are using Hidden Class &lt;code&gt;C2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look up offset in the blueprint&lt;/strong&gt;: It consults the &lt;code&gt;C2&lt;/code&gt; blueprint and sees that the &lt;code&gt;email&lt;/code&gt; property is always at a fixed memory offset (e.g., offset: 1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Memory Access&lt;/strong&gt;: It jumps directly to that memory address for the given object and retrieves the value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is &lt;strong&gt;no string comparison&lt;/strong&gt; and &lt;strong&gt;no searching&lt;/strong&gt;. It's as fast as accessing a property in a low-level, compiled language like C++. This optimization transforms the slow, dynamic lookup into a simple calculation: &lt;code&gt;object_memory_address + property_offset&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;What Breaks the Optimization?&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;This speed boost only works if objects share a &lt;strong&gt;Hidden Class&lt;/strong&gt;. If you &lt;u&gt;add or delete properties&lt;/u&gt; or &lt;u&gt;change their order&lt;/u&gt;, V8 has to create a new blueprint and can't use the same optimized path.&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;user1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jane@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Uses Hidden Class C2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Different order -&amp;gt; New Hidden Class C3!&lt;/span&gt;

&lt;span class="nx"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This forces user1 to transition to yet another Hidden Class.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why a common performance tip for JavaScript is to always initialize your objects with the same structure and avoid adding or removing properties after creation.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Express Lane in Action
&lt;/h4&gt;

&lt;p&gt;The "Express Lane" optimization leverages this hidden class mechanism brilliantly. The process works as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;JSON.stringify&lt;/code&gt; is called on an array of user objects, all sharing the same hidden class (e.g., &lt;code&gt;C2&lt;/code&gt; from the example above).&lt;/li&gt;
&lt;li&gt;When processing the &lt;strong&gt;first object&lt;/strong&gt; in the array, the &lt;strong&gt;fast path&lt;/strong&gt; performs its standard series of checks for each property key: confirm it's not a &lt;code&gt;Symbol&lt;/code&gt;, ensure it's enumerable, and scan the key string for characters that require escaping.   &lt;/li&gt;
&lt;li&gt;If all keys pass these checks, V8 does something clever: it attaches a special flag to the object's hidden class (&lt;code&gt;C2&lt;/code&gt;), marking it as &lt;code&gt;"fast-json-iterable"&lt;/code&gt;. Think of this as putting a "fast pass" sticker on the blueprint for this type of object.&lt;/li&gt;
&lt;li&gt;When V8 moves to the &lt;strong&gt;second object&lt;/strong&gt;, it first checks its hidden class. It sees that it's also &lt;code&gt;C2&lt;/code&gt; and that &lt;code&gt;C2&lt;/code&gt; has the &lt;code&gt;"fast-json-iterable"&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;This is the magic moment&lt;/strong&gt;. Because of that flag, V8 can now &lt;strong&gt;completely skip all the property key checks&lt;/strong&gt;. It already knows the keys &lt;code&gt;"id"&lt;/code&gt; and &lt;code&gt;"name"&lt;/code&gt; are safe and require no special handling. It can copy them directly to the output string buffer at maximum speed.&lt;/li&gt;
&lt;li&gt;This process repeats for every subsequent object in the array that shares the same flagged hidden class.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This optimization creates a powerful feedback loop that rewards a performance (friendly coding pattern known as &lt;strong&gt;monomorphism&lt;/strong&gt; - creating objects with consistent, predictable shapes). By structuring data consistently (e.g., always returning &lt;code&gt;{id, name, email}&lt;/code&gt; from an API endpoint), developers automatically unlock this massive performance boost, not just in &lt;code&gt;JSON.stringify&lt;/code&gt; but across many other parts of the V8 engine that rely on hidden classes for optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Hardware-Level Acceleration
&lt;/h3&gt;

&lt;p&gt;The V8 team did not stop at high-level architectural and algorithmic improvements; they pushed all the way down to the hardware level, leveraging special features of modern CPUs to accelerate the most fundamental operations: handling strings and numbers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parallel Processing in a Single Core: SIMD and SWAR
&lt;/h4&gt;

&lt;p&gt;One of the most powerful features of modern processors is &lt;strong&gt;SIMD&lt;/strong&gt; (Single Instruction, Multiple Data). In essence, SIMD allows a single CPU instruction to perform the same operation on multiple pieces of data simultaneously. A helpful analogy is applying a brightness filter in a photo editor. A traditional (scalar) approach would adjust the brightness of each pixel one by one. A SIMD-capable processor can adjust a whole block of pixels (i.e. say, 8 or 16 of them) in a single operation, dramatically speeding up the process.&lt;/p&gt;

&lt;p&gt;V8 applies this same principle to string serialization. When stringifying a value, the engine must scan the string for any characters that require special escaping, such as a double quote (&lt;code&gt;"&lt;/code&gt;) or a backslash (&lt;code&gt;\&lt;/code&gt;). Instead of checking one character at a time, V8 uses SIMD to load a large chunk of the string into a wide register and check multiple bytes at once with just a few instructions.&lt;/p&gt;

&lt;p&gt;This strategy is further refined with a two-tiered approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For longer strings&lt;/strong&gt;, V8 uses dedicated hardware SIMD instructions (like NEON on ARM CPUs or AVX2 on x86 CPUs), which are highly efficient for large blocks of data.   &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For shorter strings&lt;/strong&gt;, where the overhead of setting up hardware SIMD would be too high, V8 uses a technique called &lt;strong&gt;SWAR&lt;/strong&gt; (SIMD Within A Register). This approach uses clever bitwise logic on standard CPU registers to process multiple characters at once with very low overhead.   &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a chunk is scanned and found to contain no special characters (which is the most common case) the entire chunk can be copied directly to the output buffer, making the process incredibly efficient.&lt;/p&gt;

&lt;p&gt;Here’s a summary of where you can find CPUs that support SIMD instructions - AVX2 or NEON—across AWS, GCP, and laptops:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;SIMD Support&lt;/th&gt;
&lt;th&gt;Example Instances / Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS (x86 EC2)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AVX2, AVX-512&lt;/td&gt;
&lt;td&gt;C5/C5d, M5, T3 (Intel Skylake/Cascade Lake)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS (ARM EC2)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NEON&lt;/td&gt;
&lt;td&gt;Graviton2 (2×128-bit NEON): M6g, C6g, etc.; Graviton3 (4×128-bit NEON + SVE): C7g, M7g, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GCP (Compute Engine)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AVX2 / AVX-512&lt;/td&gt;
&lt;td&gt;Use “min CPU platform” to ensure Cascade Lake/Ice Lake (AVX2/possibly AVX-512)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Laptops (Intel)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AVX2/AVX-512&lt;/td&gt;
&lt;td&gt;Recent-gen Intel Core i5/i7/i9 mostly supports AVX2; newer Ice Lake+ may include AVX-512&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Laptops (ARM)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NEON&lt;/td&gt;
&lt;td&gt;Apple M-series or ARM-based laptops include NEON SIMD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  A Faster Number-to-String Algorithm: &lt;strong&gt;Dragonbox&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Converting a floating-point number into its shortest, most accurate string representation is a notoriously complex computer science problem. For this task, V8 upgraded its core &lt;strong&gt;DoubleToString&lt;/strong&gt; algorithm, replacing the long-serving &lt;strong&gt;&lt;a href="https://github.com/kring/grisu.net" rel="noopener noreferrer"&gt;Grisu3&lt;/a&gt;&lt;/strong&gt; algorithm with a state-of-the-art implementation called &lt;strong&gt;&lt;a href="https://github.com/jk-jeon/dragonbox" rel="noopener noreferrer"&gt;Dragonbox&lt;/a&gt;&lt;/strong&gt;.   &lt;/p&gt;

&lt;p&gt;While this change was driven by profiling &lt;code&gt;JSON.stringify&lt;/code&gt;, its benefits extend far beyond it. This is a "rising tide lifts all boats" improvement (general growth helps everyone). The new &lt;strong&gt;Dragonbox&lt;/strong&gt; implementation benefits all calls to &lt;code&gt;Number.prototype.toString()&lt;/code&gt; throughout the entire V8 engine. This means any JavaScript code that converts numbers to strings, not just JSON serialization, automatically receives this performance boost for free. This is a hallmark of efficient engineering: solving a specific problem by improving a shared, foundational component, thereby creating widespread, positive ripple effects across the platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Smart Memory Management
&lt;/h3&gt;

&lt;p&gt;When building a very large JSON string, which can sometimes be hundreds of megabytes in size, memory management becomes a critical performance factor. The previous implementation of &lt;code&gt;JSON.stringify&lt;/code&gt; faced a significant bottleneck related to how it handled its temporary output buffer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐌 The Old Way...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Previously, the stringifier built its output in a single, contiguous block of memory on the C++ heap. Imagine writing a very long document in a single notebook. As the JSON string grew, this memory block would eventually run out of space. When that happened, V8 had to perform a costly sequence of operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Allocate a new, larger block of memory (like getting a bigger notebook).&lt;/li&gt;
&lt;li&gt;Copy the entire existing content from the old, full buffer to the new, larger one.&lt;/li&gt;
&lt;li&gt;Deallocate the old buffer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For very large JSON objects, this cycle of re-allocation and copying became a major performance bottleneck. Copying hundreds of megabytes of data is a slow, resource-intensive operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 The New Way...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The V8 engineers had a crucial insight: the temporary buffer only needs to be a single, contiguous string at the very end of the process. While the string is being built, it can exist in pieces.   &lt;/p&gt;

&lt;p&gt;With this in mind, they replaced the old system with a &lt;strong&gt;Segmented Buffer&lt;/strong&gt;. Instead of one large, growing block, the new stringifier uses a list of smaller, fixed-size buffers, or "segments" — much like using a series of small sticky notes instead of one giant page. When one segment is full, V8 simply allocates a new one and continues writing there. This completely eliminates the expensive copy operations.&lt;/p&gt;

&lt;p&gt;This is vastly more efficient because you have eliminated all the intermediate copying steps. The expensive "joining" operation is only performed once, right at the end.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old Way (Contiguous Buffer)&lt;/th&gt;
&lt;th&gt;New Way (Segmented Buffer)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Analogy&lt;/strong&gt;: One single, growing scroll.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Analogy&lt;/strong&gt;: A stack of sticky notes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Process&lt;/strong&gt;: Write, run out of space, copy everything to a bigger scroll, repeat.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Process&lt;/strong&gt;: Write on a note, grab a new one when full, repeat.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Bottleneck&lt;/strong&gt;: The slow, repeated copying of large amounts of data.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Benefit&lt;/strong&gt;: No intermediate copying. The expensive "join" happens only once at the end.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These segments are allocated in V8's &lt;strong&gt;Zone memory&lt;/strong&gt;, a special memory pool optimized for very fast, short-lived allocations, which further reduces management overhead. At the very end, when the entire object has been processed, all these smaller segments are efficiently joined together to form the final, complete JSON string. This change in the intermediate data structure is a classic example of a performance engineering trade-off: the logic to manage a list of buffers is slightly more complex, but it eliminates a major performance cliff, making it a worthwhile investment for a critical function like &lt;code&gt;JSON.stringify&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Stay on the Fast Path (and When You Can't)
&lt;/h2&gt;

&lt;p&gt;These incredible performance improvements are available automatically in V8 version 13.8 (found in Chrome 138) and later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;br&gt;
As of Node.js 24, the V8 engine version included is 13.6, not 13.8. Thus, no stable or current Node.js release is using V8 13.8 as of mid‑August 2025&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Chrome&lt;/strong&gt;&lt;br&gt;
Performance improvements (like faster &lt;code&gt;JSON.stringify&lt;/code&gt;) are confirmed to be available starting in Chrome 138, which uses V8 13.8&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The following table provides a quick-reference guide for developers aiming to maximize &lt;code&gt;JSON.stringify&lt;/code&gt; performance.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature / Condition&lt;/th&gt;
&lt;th&gt;Consequence&lt;/th&gt;
&lt;th&gt;Rationale for Fallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;replacer&lt;/code&gt; function provided&lt;/td&gt;
&lt;td&gt;Falls back to general serializer.&lt;/td&gt;
&lt;td&gt;V8 cannot make assumptions about arbitrary user code. The replacer could introduce side effects or complex logic that the fast path is not designed to handle.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;space&lt;/code&gt; argument provided&lt;/td&gt;
&lt;td&gt;Falls back to general serializer.&lt;/td&gt;
&lt;td&gt;The logic for pretty-printing (inserting spaces, newlines) is separate from the core task of fast serialization and is handled by the more versatile general path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object has a &lt;code&gt;.toJSON()&lt;/code&gt; method&lt;/td&gt;
&lt;td&gt;Falls back to general serializer.&lt;/td&gt;
&lt;td&gt;This invokes a user-defined method during serialization, which is considered a potential side effect. V8 must execute this code, so it uses the general path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array of objects with inconsistent shapes&lt;/td&gt;
&lt;td&gt;Stays on fast path, but disables the "Express Lane."&lt;/td&gt;
&lt;td&gt;The core fast path can still be used, but V8 cannot reuse the hidden class information. It must individually check the properties of each differently-shaped object, losing the major speedup of the "Express Lane."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object with array-like indexed properties&lt;/td&gt;
&lt;td&gt;Falls back to general serializer.&lt;/td&gt;
&lt;td&gt;Objects with numeric keys (e.g., '0', '1') are handled differently internally than objects with string keys, particularly regarding property ordering. This requires the more complex logic of the general path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object contains Symbol-keyed properties&lt;/td&gt;
&lt;td&gt;Property is ignored (standard behavior).&lt;/td&gt;
&lt;td&gt;The fast path must still check for Symbols on the first object of a given shape. The "Express Lane" then assumes no Symbols exist for subsequent objects of the same shape.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Reference: &lt;a href="https://v8.dev/blog/json-stringify" rel="noopener noreferrer"&gt;https://v8.dev/blog/json-stringify&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>v8</category>
      <category>jsonstringify</category>
    </item>
  </channel>
</rss>
