<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bytes - The Best JavaScript Newsletter]]></title><description><![CDATA[Bytes - The Best JavaScript Newsletter]]></description><link>https://bytes.dev/archives</link><image><url>https://bytes.dev/images/bytes-icon.png</url><title>Bytes - The Best JavaScript Newsletter</title><link>https://bytes.dev/archives</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Apr 2025 08:51:40 GMT</lastBuildDate><atom:link href="https://rsstree.netlify.app/.netlify/functions/rss-bytes" rel="self" type="application/rss+xml"/><item><title><![CDATA[RIP Records & Tuples]]></title><description><![CDATA[Dan found the password to his blog, we go deep on structural equality, and Git turns 20.]]></description><link>https://bytes.dev/archives/385</link><guid isPermaLink="false">385</guid><pubDate>Fri, 18 Apr 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> Dan found the password to his blog, we go deep on structural equality, and Git turns 20.</p>
<p>Welcome to <a href="https://bytes.dev/archives/385">#385</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/ripmeme.jpg" alt="A lego man mourning another dead lego man" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">You were the chosen one </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>RIP Records &amp; Tuples</h3><p>The Bible clearly teaches us that <em>TC39 giveth, and TC39 taketh away.</em></p><p>And the SpecLords tested our faith again this week when they killed the Records and Tuples proposal, which had promised to bring deep immutability and structural equality to complex data in JavaScript.</p><p>Now in their place stands a new Stage-1 proposal called <a href="https://github.com/tc39/proposal-composites">Composites</a>, which tries to solve similar problems with a very different approach.</p><p>Let’s take a closer look:</p><ul>
<li>
<p><strong>Composites are frozen, not deeply immutable</strong> – Composites can contain any value, so immutability is based on the contents. Since R&amp;T could only contain primitives and other R&amp;T, they had forced deep immutability by design.</p>
</li>
<li>
<p><strong>Containment is unrestricted</strong> – Unlike R&amp;T, Composites can hold objects, symbols, functions, and whatever else you throw at them.</p>
</li>
<li>
<p><strong>Structural equality via <code>Composite.equal(a, b)</code></strong> – This does a recursive deep comparison using <code>SameValueZero</code>, but you must call it manually because there’s no special behavior with <code>===</code>.</p>
</li>
<li>
<p><strong>No new syntax or <code>typeof</code> values</strong> – Composites are standard objects, so they integrate with your existing code and APIs (<code>Map</code>, <code>Set</code>, etc.) without language-level changes</p>
</li>
<li>
<p><strong>Ergonomics take a hit</strong> – You lose the elegance of native <code>===</code> structural equality and literal syntax like <code>#{}</code>. Everything is more verbose and opt-in.</p>
</li>
</ul><p><strong>Bottom Line:</strong> Records &amp; Tuples were clearly a more elegant solution, but Composites are more flexible. And as Scott Tolinski taught me at breakdance camp last summer, flexibility usually beats elegance.</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/385" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F385" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=Why%20the%20TC39%20committee%20killed%20Records%20and%20Tuples%2C%20and%20what%20they're%20cooking%20up%20instead%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F385" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0AWhy%20the%20TC39%20committee%20killed%20Records%20and%20Tuples%2C%20and%20what%20they're%20cooking%20up%20instead%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F385" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/meticulous-logo.png" alt="Meticulous logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/raccoon-guitar.jpg" alt="A raccoon with a magic wand" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Me after using AI to do the absolute worst part of my job </p></div><h3><a href="https://www.meticulous.ai/?utm_source=bytes_newsletter&amp;utm_campaign=bytes_newsletter18thapril2025">Meticulous AI gets your app full test coverage – without you writing any tests</a></h3><p>Dropbox, Lattice, and hundreds of other engineering orgs all rely on Meticulous because it generates and maintains an exhaustive suite of E2E UI tests with <em>zero developer effort.</em></p><p>That means you’ll never write, fix, or maintain a test ever again. <strong>Here’s how it works:</strong></p><ul>
<li>
<p>Add a script tag to your local development, staging, and preview URL environments, so Meticulous can monitor your daily interactions with your app</p>
</li>
<li>
<p>Their AI engine uses that info to generate a <a href="https://www.meticulous.ai/how-it-works/?utm_source=bytes_newsletter&amp;utm_campaign=bytes_newsletter18thapril2025">continuously evolving test suite</a> that adds or removes tests as needed and eliminates flakes</p>
</li>
<li>
<p>Tests are heavily parallelized across a compute cluster, so you can test thousands of screens and get results in under 120 seconds.</p>
</li>
</ul><p><a href="https://www.meticulous.ai/?utm_source=bytes_newsletter&amp;utm_campaign=bytes_newsletter18thapril2025">Check it out</a> – and see why one engineering leader at Dropbox said that “once we started using Meticulous, we couldn’t imagine working without it.”</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://www.datadoghq.com/resources/synthetic-monitoring-product-brief/?utm_source=bytesdev&amp;utm_medium=newsletter&amp;utm_campaign=dg-apm-ww-synthetics-brief-bytes">Datadog</a></h4><p><em>Their <a href="https://www.datadoghq.com/resources/synthetic-monitoring-product-brief/?utm_source=bytesdev&amp;utm_medium=newsletter&amp;utm_campaign=dg-apm-ww-synthetics-brief-bytes">Synthetic Monitoring Brief</a> shows you how to efficiently create browser and API tests that are intelligent and self-maintaining.</em></p></div></div>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> people <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Aaron"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Smith"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Émile"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Zola"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Charlotte"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Brown"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Beyoncé"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Knowles"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Ólafur"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Arnalds"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Jones"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Zoë"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Deschanel"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">sortAlphabetically</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>firstName <span class="token operator">&lt;</span> b<span class="token punctuation">.</span>firstName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>firstName <span class="token operator">&gt;</span> b<span class="token punctuation">.</span>firstName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">sortAlphabetically</span><span class="token punctuation">(</span>people<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p>Thorsten Ball wrote about how <a href="https://ampcode.com/how-to-build-an-agent">it’s not that hard to build a fully functioning, code-editing agent</a>.</p>
</li>
<li>
<p>Atriiy wrote about <a href="https://www.atriiy.dev/blog/rolldown-module-loader-and-dependency-graph">how Rolldown works</a>.</p>
</li>
<li>
<p><a href="https://go.clerk.com/eQzt5Ea">How to integrate Clerk with your Lovable application</a> shows how you can use just a few prompts and config steps to add custom domains, streamlined auth flows, and waitlist-powered onboarding to your app. [sponsored]</p>
</li>
<li>
<p>Mark Dalgleish wrote about <a href="https://remix.run/blog/faster-lazy-loading">React Router’s new API for faster lazy loading</a>.</p>
</li>
<li>
<p>Dan Abramov wrote about <a href="https://overreacted.io/jsx-over-the-wire/">JSX over the Wire</a> and shot us all back to 2019 by releasing two blog posts in one month.</p>
</li>
<li>
<p>Isaac Maw from Apryse wrote about <a href="https://apryse.com/blog/document-processing-trends-predictions-2025?utm_source=bytes.dev&amp;utm_medium=newsletter&amp;utm_campaign=04172025">4 document processing trends</a> they saw in 2024 and what they predict will change the most in 2025. [sponsored]</p>
</li>
<li>
<p>Git is turning 20 years old this month, and Linus Torvalds says that <a href="https://devclass.com/2025/04/11/20-years-of-git-never-a-big-thing-for-me-says-inventor-linus-torvalds/">“it was never a big thing for me”</a>. Classic Liney-T.</p>
</li>
<li>
<p><a href="https://astro.build/blog/astro-570">Astro 5.7</a> now supports local SVG files as components.</p>
</li>
<li>
<p><a href="https://bit.cloud/?utm_source=Bytes">bit.cloud</a> lets you use AI to build new full-stack features as reusable components that can be installed in your team’s existing applications. Bit’s HopeAI generates high quality code, based on your dev standards and tech stack. [sponsored]</p>
</li>
<li>
<p>Fotis wrote about <a href="https://fotis.xyz/posts/the-new-cookie-store-api/">the new Cookie Store API</a> that can finally help you put those Girl Scouts in their place.</p>
</li>
<li>
<p><a href="https://v4.zod.dev/v4">The Zod 4 beta</a> is “faster, slimmer, and more <code>tsc</code>-efficient”, which is exactly how I felt after my 6th injection of Wegovy.</p>
</li>
<li>
<p>Ondrej Velisek wrote about <a href="https://ondrejvelisek.github.io/avoid-state-synchronization-trap/">avoiding the State Synchronization trap</a>.</p>
</li>
</ol>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug: Solution</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://www.datadoghq.com/resources/synthetic-monitoring-product-brief/?utm_source=bytesdev&amp;utm_medium=newsletter&amp;utm_campaign=dg-apm-ww-synthetics-brief-bytes">Datadog</a></h4></div></div>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> people <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Aaron"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Smith"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Émile"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Zola"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Charlotte"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Brown"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Beyoncé"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Knowles"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Ólafur"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Arnalds"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Jones"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Zoë"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Deschanel"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">sortAlphabetically</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>firstName <span class="token operator">&lt;</span> b<span class="token punctuation">.</span>firstName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>firstName <span class="token operator">&gt;</span> b<span class="token punctuation">.</span>firstName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">sortAlphabetically</span><span class="token punctuation">(</span>people<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>By default, string comparison in JavaScript is not language-sensitive (meaning it doesn’t take into account language-specific rules or special characters like accents), which results in the sorted list not being in the correct order.</p>
<p>The solution is to leverage <code>Intl.Collator</code> which enables language-sensitive string comparison.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sortAlphabetically</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> collator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Intl<span class="token punctuation">.</span>Collator</span><span class="token punctuation">(</span><span class="token string">"en"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">sensitivity</span><span class="token operator">:</span> <span class="token string">"base"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> collator<span class="token punctuation">.</span><span class="token function">compare</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>firstName<span class="token punctuation">,</span> b<span class="token punctuation">.</span>firstName<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></body></html>]]></content:encoded></item><item><title><![CDATA[Cloudchella 2025]]></title><description><![CDATA[The 12,000-word Node.js ebook that should've been a tweet, slopsquatting, and the missing piece to my Rammstein fansite.]]></description><link>https://bytes.dev/archives/384</link><guid isPermaLink="false">384</guid><pubDate>Mon, 14 Apr 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> The 12,000-word Node.js ebook that should’ve been a tweet, “slopsquatting”, and the missing piece to my Rammstein fansite.</p>
<p>Welcome to <a href="https://bytes.dev/archives/384">#384</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/racoon-praise.jpg" alt="Raccoons praying on a mountain top" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Blessed be the workers </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>Cloudchella 2025</h3><p>Am I a <em>little</em> jealous that I wasn’t able to scream along in person to every word of Lady Gaga’s Coachella set last weekend? Of course I am.</p><p>But I was busy having a different out-of-body experience during my annual pilgrimage to the top of Cloudflare Mountain for their 2025 Developer Week. And it wasn’t just the CF-branded molly tabs that Matthew Prince was handing out in that cave – it was the 32 different announcements they made during a dizzying 5-day stretch that puts most other launch weeks to shame.</p><p>Here are three of our favorites.</p><p><strong>Cloudflare Containers coming in June:</strong> This will allow you to run user-generated code in any language, execute CLI tools that need a full Linux environment, and <a href="https://blog.cloudflare.com/cloudflare-containers-coming-2025">lots of other container-y things</a> in a simple and scalable way. Containers will integrate deeply with Workers and Durable Objects, so you’ll be able to use Workers as your API gateway, service mesh, and orchestrator – without having to bolt on a bunch of extra infrastructure.</p><p><strong>Cloudflare Vite plugin 1.0:</strong> Historically, the Vite dev server has always run server code in Node.js, even if you were targeting Workers. But thanks to Vite’s new Environment API, your Worker code can now run inside the <a href="https://github.com/cloudflare/workerd">native CF Workers runtime</a>, letting your local dev environment match production behavior almost exactly.</p><p><strong>MCP comes to the Agents SDK:</strong> You knew there had to be some AI <del>slop</del> <em>hype</em> in here, but this is pretty interesting. The <a href="https://agents.cloudflare.com/">Agents SDK</a> is already popular for letting you build powerful AI agents with Durable Objects and Vectorize. Now, they’re adding in a new class, <code>MCPClientManager</code>, along with some other <a href="https://blog.cloudflare.com/building-ai-agents-with-mcp-authn-authz-and-durable-objects/">MCP capabilities</a> that provide all the tooling you need to allow your AI agent to make calls to external services via MCP.</p><p><strong>Bottom Line:</strong> Love them or hate them, we all have to admit one thing – Cloudflare ships. And Matt still owes me $65 for that Uber.</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/384" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F384" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=Breaking%20down%20the%203%20coolest%20things%20%40CloudflareDev%20shipped%20during%20Cloudflare%20Developer%20Week%202025%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F384" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0ABreaking%20down%20the%203%20coolest%20things%20%40CloudflareDev%20shipped%20during%20Cloudflare%20Developer%20Week%202025%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F384" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/qa-wolf-logo.png" alt="QA Wolf logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/edna.jpg" alt="Edna Mode from the Incredibles staring into the camera" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Me watching all of my tests slowly fail one by one </p></div><h3><a href="https://www.qawolf.com?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_Ship5xFaster_20250414-None_Experiment-FALSE&amp;utm_term=headline-Ship5xFasterWithQAWolf&amp;utm_content=Ship5xFaster_GetAPersonalizedDemo_None_Headline%3AShip5xFasterWithQAWolf____Newsletter-PrimaryPlacement_20250414_v1_">Ship 5x faster with QA Wolf</a></h3><p>They helped Napster’s engineering team build out an entire test suite in under 30 days that dramatically sped up QA cycles, reduced bugs, and offset the need to hire four QA engineers (<a href="https://www.qawolf.com/case-studies/napster?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_Ship5xFaster_20250414-None_Experiment-FALSE&amp;utm_term=body-SeeCaseStudy&amp;utm_content=Ship5xFaster_GetAPersonalizedDemo_None_Headline%3AShip5xFasterWithQAWolf____Newsletter-PrimaryPlacement_20250414_v1_">see the case study</a>).</p><p>And they could help your team do the same. Here’s how:</p><ul>
<li>
<p>They create, maintain, and <a href="https://www.qawolf.com/how-it-works?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_Ship5xFaster_20250414-None_Experiment-FALSE&amp;utm_term=body-RunPlaywrightTests&amp;utm_content=Ship5xFaster_GetAPersonalizedDemo_None_Headline%3AShip5xFasterWithQAWolf____Newsletter-PrimaryPlacement_20250414_v1_">run Playwright tests</a> to cover your entire application</p>
</li>
<li>
<p>They get you pass/fail results within 3 min and provide unlimited parallel test runs on their infrastructure</p>
</li>
<li>
<p>Every failed test is reviewed by their team of <a href="https://www.qawolf.com/how-it-works?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_Ship5xFaster_20250414-None_Experiment-FALSE&amp;utm_term=body-HumanQAEngineers&amp;utm_content=Ship5xFaster_GetAPersonalizedDemo_None_Headline%3AShip5xFasterWithQAWolf____Newsletter-PrimaryPlacement_20250414_v1_">human QA engineers</a>, so you get zero flakes</p>
</li>
</ul><p>92% of their customers release faster, and they save 9 hours/week <em>per engineer</em> on average.</p><p><a href="https://www.qawolf.com/schedule-a-demo?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_Ship5xFaster_20250414-None_Experiment-FALSE&amp;utm_term=cta-GetAPersonalizedDemo&amp;utm_content=Ship5xFaster_GetAPersonalizedDemo_None_Headline%3AShip5xFasterWithQAWolf____Newsletter-PrimaryPlacement_20250414_v1_">Get a personalized demo</a> – and see if they can speed up your team’s release cycles.</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p>If you want to see some of the new Cloudflare hotness in action, Bhanu just launched <a href="https://mcpify.ai/">MCPify.ai</a> – a Bolt-like tool for building your own MCP servers, which he created using Cloudflare Workers + Durable Objects.</p>
</li>
<li>
<p><a href="https://tailwindcss.com/blog/tailwindcss-v4-1">Tailwind CSS 4.1</a> comes with some long-awaited <code>text-shadow</code> utilities, mask elements, and fine-grained text wrapping that’ll “defend the integrity of your layouts from even the longest German words your users will throw at you.” Time to fire up my old Rammstein fansite and get to work.</p>
</li>
<li>
<p><a href="https://nextjs.org/blog/next-15-3">Next.js 15.3</a> comes with Turbopack builds (alpha) and two new navigation hooks, <code>onNavigate</code> and <code>useLinkStatus</code> for better client-side routing.</p>
</li>
<li>
<p>Right on cue, the Blazity team created <a href="https://blazity.com/the-expert-guide-to-nextjs-performance-optimization?utm_source=newsletter&amp;utm_medium=email&amp;utm_campaign=ebook-guide-next-js-performance-optimization&amp;utm_content=bytes">The expert guide to Next.js performance optimization</a> – a 10-chapter ebook with practical strategies, real-life examples, and open-source tools to help make your Next.js app faster and more user friendly. [sponsored]</p>
</li>
<li>
<p>Google just relaunched Project IDX as <a href="https://firebase.studio/">Firebase Studio</a> and added more AI tools and features for building full-stack apps in the browser. Hopefully this rebrand goes better than when my high school band changed our name to Weezer 2.</p>
</li>
<li>
<p>Jordan Eldredge wrote an article called <a href="https://jordaneldredge.com/blog/transitions-f-of-state/"><code>{transitions} = f(state)</code></a> about how a React application can be thought of as modeling a state machine.</p>
</li>
<li>
<p><a href="https://convex.link/bytesOSS">This Convex repo</a> contains the entire codebase for their reactive database, which they just open-sourced last month. [sponsored]</p>
</li>
<li>
<p><a href="https://github.com/goldbergyoni/nodejs-testing-best-practices#readme">Node.js Testing Best Practices</a> is a very in-depth, 12,000-word ebook that the authors published in a GitHub readme. I look forward to reading their next ebook in an even more user-friendly format – hundreds of text screenshots that you swipe through on a LinkedIn post.</p>
</li>
<li>
<p><a href="https://webtui.ironclad.sh/">WebTUI</a> is a modular CSS library that “brings the beauty of Terminal UIs to the browser.” I double-checked, and I’m 90% sure they weren’t being sarcastic with that description.</p>
</li>
<li>
<p>Expo created this new page showing you <a href="https://expo.dev/codepush/bytes">how to migrate seamlessly from CodePush to EAS Update</a> – and considering CodePush just got axed by Microsoft for good, it’s pretty helpful. [sponsored]</p>
</li>
<li>
<p>In a new development that absolutely no one saw coming, <a href="https://www.theregister.com/AMP/2025/04/12/ai_code_suggestions_sabotage_supply_chain/">LLMs are hallucinating package names and making up software dependencies</a> – which is creating a fun new trend called “slopsquatting” that may or may not eventually threaten the security of the entire internet.</p>
</li>
<li>
<p>But on the other hand, have you ever wondered <a href="https://simonsafar.com/2025/json_with_no_commas/">why JSON has commas?</a></p>
</li>
</ol></div></body></html>]]></content:encoded></item><item><title><![CDATA[Barenaked Runtimes]]></title><description><![CDATA[Escaping the vulnerability police, trusting your JavaScript doctor, and stimulating the global economy with REST APIs.]]></description><link>https://bytes.dev/archives/383</link><guid isPermaLink="false">383</guid><pubDate>Fri, 11 Apr 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> Escaping the vulnerability police, trusting your JavaScript doctor, and stimulating the global economy with REST APIs.</p>
<p>Welcome to <a href="https://bytes.dev/archives/383">#383</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/ken-sax.jpg" alt="Ken Jeong playing a big saxophone" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Me serenading you about a new JS runtime you've never heard of </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>Barenaked Runtimes</h3><p><a href="https://youtu.be/fC_q9KPczAg?t=2">It’s been one week</a> since we got a new JS runtime – but this time, it’s not about a bunch of fancy new features, it’s about a return to simplicity <span role="img" aria-label="man in lotus position">🧘‍♂️</span>.</p><p><a href="https://bare.pears.com">Bare</a> describes itself as a “stripped-down, minimal JS runtime” that, much like Season 3 of <em>White Lotus</em>, takes pride in giving you as little as possible. It doesn’t provide a standard library beyond the core JavaScript API or any other assumptions about how you’ll build.</p><p>Instead, Bare lets you compose your environment from an ecosystem of small, purposeful modules that work seamlessly across desktop and mobile and are easily embeddable. Let’s take a closer look at how the sausage gets made:</p><ul>
<li>
<p><strong>Works with any JS engine</strong> – Bare abstracts over the underlying engine and platform I/O using <code>libjs</code> and <code>libuv</code>, so it can plug into JavaScriptCore, V8, QuickJS, and more.</p>
</li>
<li>
<p><strong>Runs anywhere</strong> – Bare is designed to be portable across platforms, with native bindings that let you easily run the same code on iOS, Android, Windows, Linux, etc. One might even say you can <em>“write once, run anywhere.”</em></p>
</li>
<li>
<p><strong>Supports CJS and ESM with bi-directional interop</strong> – You can <code>require</code> an ES Module from CommonJS and <code>import</code> a CJS module from ESM, which makes migration and compatibility silky smooth.</p>
</li>
</ul><p><strong>Bottom Line:</strong> Bare isn’t trying to out-feature Node, Deno, or Bun. It’s trying to be the IKEA of JS runtimes – giving you a minimal box of parts, some loose instructions, and the freedom to build exactly what you need without destroying your marriage in the process.</p><p><em>Because it’ll still be two days til we say we’re sorry.</em></p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/383" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F383" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=Breaking%20down%20the%20hottest%20new%20JS%20runtime%20from%20the%20%40Pears_p2p%20team%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F383" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0ABreaking%20down%20the%20hottest%20new%20JS%20runtime%20from%20the%20%40Pears_p2p%20team%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F383" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/gitkraken-logo.png" alt="GitKraken logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/irobot-smile.jpg" alt="The iRobot robot smiling" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">When AI can do all my Git tasks for me </p></div><h3><a href="https://www.gitkraken.com/solutions/gitkraken-ai?source=email&amp;product=gitkraken&amp;utm_source=bytes_dev_newsletter&amp;utm_medium=email&amp;utm_campaign=sponsored">GitKraken AI is built to assist you – not replace you</a></h3><p>It brings a bunch of powerful Git automations to your daily workflow to help you eliminate tedious and repetitive Git tasks forever.</p><p>Here are a few examples of what it can do:</p><ul>
<li>
<p>Generate commit messages, stash messages, changelogs, and much more</p>
</li>
<li>
<p>Provide explanations of what’s going on, so you don’t have to waste time guessing</p>
</li>
<li>
<p>Create <a href="https://www.gitkraken.com/solutions/gitkraken-ai?source=email&amp;product=gitkraken&amp;utm_source=bytes_dev_newsletter&amp;utm_medium=email&amp;utm_campaign=sponsored">smarter workflows</a> with built-in structure and visibility that leaders can trust</p>
</li>
</ul><p>It’s like a copilot for your entire Git workflow, automating everything that slows you down while still giving you full control.</p><p><a href="https://www.gitkraken.com/solutions/gitkraken-ai?source=email&amp;product=gitkraken&amp;utm_source=bytes_dev_newsletter&amp;utm_medium=email&amp;utm_campaign=sponsored">Try it out for free</a> – it works seamlessly in your IDE, terminal, desktop, or browser with all the tools you already use.</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p>Dan Abramov wrote an article called <a href="https://overreacted.io/react-for-two-computers/">React for Two Computers</a>, but seemingly forgot to check his privilege and realize that most of us can barely afford one computer right now.</p>
</li>
<li>
<p><a href="https://waku.gg/blog/api-routes">Waku v0.22</a> is a major re-architecture for the React framework, and it now supports API routes.</p>
</li>
<li>
<p>Augment Code just launched <a href="https://fnf.dev/4ijQcg8">the first coding agent for large codebases</a>. It helps you master your team’s most complex repos, it understands your team’s best practices, and it’s fully compatible with your IDE and other tools (VSCode, JetBrains, Vim, GitHub, etc). [sponsored]</p>
</li>
<li>
<p>Ryan Dahl wrote about <a href="https://deno.com/blog/deno-v-oracle3">Round 3 of Deno vs Oracle</a> in the trademark battle for the ages. At this point, I don’t really remember how or why this got started, but I think we can all agree that Oracle is wrong.</p>
</li>
<li>
<p><a href="https://animate-ui.com/">Animate UI</a> is a fully animated component distribution built with React, TS, Tailwind, and Motion.</p>
</li>
<li>
<p>Unlike other observability tools, Sentry <a href="https://sentry.io/lp/make-it-make-sense/?utm_source=bytes&amp;utm_medium=paid-community&amp;utm_campaign=general-fy26q1-mims&amp;utm_content=newsletter-dashboards-startfree">hands you real context about your code</a> – instead of just showing you another graph about how something’s broken. Their stack traces, replays, and commits are designed to cut through the noise and help you fix your code ASAP. [sponsored]</p>
</li>
<li>
<p><a href="https://reactnative.dev/blog/2025/04/08/react-native-0.79">React Native 0.79</a> just launched with a much faster version of the Metro bundler and a few other QOL improvements.</p>
</li>
<li>
<p>The group who discovered the Next.js vulnerability last month just discovered a fun new <a href="https://zhero-web-sec.github.io/research-and-things/react-router-and-the-remixed-path">React Router/Remix vulnerability</a>. Pray they don’t come for you next.</p>
</li>
<li>
<p>Are you still sitting up late at night wondering <a href="https://go.clerk.com/vvj8oQt">How Clerk integrates with Supabase</a>? Well now you can finally sleep soundly, because the Clerk team’s new in-depth guide covers it all just for you. [sponsored]</p>
</li>
<li>
<p>Dr. Axel “trust-me-I’m-a-doctor” Rauschmayer wrote about whether <a href="https://2ality.com/2025/03/sync-await.html">JavaScript could ever have synchronous <code>await</code></a>.</p>
</li>
<li>
<p><a href="https://webkit.org/blog/16574/webkit-features-in-safari-18-4/">Safari 18.4</a> comes with a whopping 84 new features, and Jen Simmons promised to perform an original ballad at my birthday party explaining each one in detail.</p>
</li>
<li>
<p>The Chainsmokers are <a href="https://x.com/boltdotnew/status/1909617944277270674">playing at Bolt’s Hackathon</a>, Ryan Reynolds is <a href="https://x.com/Brycicle77/status/1910370753616482675">speaking at the Postman conference</a>, and you’re worried about the global economy right now?? Trade war, shmade war – the guy from Deadpool is gonna get paid $500k to pretend to care about REST APIs for an hour. We’re fine!</p>
</li>
</ol></div></body></html>]]></content:encoded></item><item><title><![CDATA[The Great (React) Divide]]></title><description><![CDATA[The king of pop state, the return of Devin, and saying goodbye to styled-components]]></description><link>https://bytes.dev/archives/382</link><guid isPermaLink="false">382</guid><pubDate>Mon, 07 Apr 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> The king of pop state, the return of Devin, and saying goodbye to styled-components.</p>
<p>Welcome to <a href="https://bytes.dev/archives/382">#382</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/juggalo-guy.jpg" alt="A juggalo" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">I've been down with the clown since React.createClass </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>The Great React Divide</h3><p>If you’ve been feeling fulfilled over the last few years, you probably missed that React recently hit puberty, started rage listening to Insane Clown Posse, and has seemingly changed its whole identity.</p><p>And despite some trepidation from prominent community members, React swears it’s not just a phase.</p><p><strong>So how did we get here</strong> and why are some in the React ecosystem so upset?</p><p>Let’s start with some code.</p><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> getAnalyticsCSV <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./api"</span>
<span class="token keyword">import</span> Papa <span class="token keyword">from</span> <span class="token string">"papaparse"</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">Dashboard</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> analytics <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getAnalyticsCSV</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> results <span class="token operator">=</span> Papa<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>analytics<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">header</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> rows <span class="token operator">=</span> results<span class="token punctuation">.</span>data

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>table<span class="token operator">&gt;</span>
      <span class="token operator">...</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>table<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><p>This is a perfectly valid React Server Component. It doesn’t need to follow the traditional rules of React (like not fetching data during render) because it doesn’t have the same constraints as a typical React component.</p><p>Server Components also come with some performance benefits around shrinking bundle sizes and optimizing time to first paint and interaction.</p><p><strong>So why’s everyone so upset?</strong> Cause they contain more magic than the night in Las Vegas when Criss Angel hypnotized me and put a devil in my body.</p><p>To make RSCs work, you need three things – a (smart) bundler, a server that can take the bundle and stream it to the client, and a router that can request and process the stream from the server.</p><p>As Netlify CEO <a href="https://x.com/biilmann/status/1904985218538434643">pointed out</a>, they introduce a lot of complexity and tie together the front-end, bundling, and server runtimes for apps that “look and feel no different than the ones built without them”.</p><p><strong>Bottom Line:</strong> Are we all just addicted to complexity or are RSCs pioneering a new wave of granular, network agnostic UI? I still don’t really know, but the king of pop states <a href="https://x.com/mjackson/status/1904977249918705853">has some thoughts</a>.</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/382" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F382" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=The%20React%20ecosystem%20has%20never%20been%20more%20divided.%20The%20%40bytesdotdev%20crew%20investigates%20why.%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F382" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0AThe%20React%20ecosystem%20has%20never%20been%20more%20divided.%20The%20%40bytesdotdev%20crew%20investigates%20why.%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F382" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/progress-kendoui-logo.png" alt="progress kendoui logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/fieri-fire.jpg" alt="Guy Fieri pouring gas on a fire" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Me trying to build a data grid from scratch </p></div><h3><a href="https://www.telerik.com/kendo-react-ui/?ref=bytes">KendoReact just released 50 enterprise-grade React components for free</a></h3><p>Companies like Samsung, Visa, and Microsoft pay good money to use enterprise React components from Telerik and Kendo UI – and now you can get 50 of their React components for free on npm. No signup required, no license key, no strings attached.</p><p>That includes their fast and powerful <a href="https://www.telerik.com/kendo-react-ui/components/grid/?ref=bytes">React Data Grid</a>, DatePicker, dropdowns, and more. And they’re all designed to save you time and help you ship polished apps faster.</p><p>Here’s what you get:</p><ul>
<li>
<p>50+ battle-tested React components, written in TypeScript with a consistent API and small bundle sizes.</p>
</li>
<li>
<p>4 professionally designed themes, 4 Figma UI kits, and <a href="https://www.telerik.com/kendo-react-ui/components/free/?ref=bytes">thorough documentation</a> to keep you moving.</p>
</li>
<li>
<p>Easy integrations with frameworks like Next.js and simple customizations, so everything fits your app perfectly.</p>
</li>
</ul><p><a href="https://www.telerik.com/kendo-react-ui/?ref=bytes">Install KendoReact Free from npm</a> – and start building enterprise apps the easy way.</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p><a href="https://opencollective.com/styled-components/updates/thank-you">styled-components is going into maintenance mode</a>. If that news makes you feel a little sad and nostalgic, might I remind you that you’re probably overdue for a prostate exam.</p>
</li>
<li>
<p><a href="https://gitmcp.io/">GitMCP</a> lets you instantly create a remote MCP server for any GitHub project by simply changing the domain from <code>github.com</code> to <code>gitmcp.io</code>. Look who just became a 10x AI developer.</p>
</li>
<li>
<p>CodeRabbit built an <a href="https://www.coderabbit.ai/?utm_source=newsletter&amp;utm_medium=bytes&amp;utm_campaign=newsletter_bytes_apr7">AI-powered code review companion</a> that deeply understands your JavaScript codebase and goes way beyond basic linting. It visualizes code changes through interactive file walkthroughs, sequence diagrams that explain component relationships – and it’s <a href="https://www.coderabbit.ai/?utm_source=newsletter&amp;utm_medium=bytes&amp;utm_campaign=newsletter_bytes_apr7">free for open source</a>. [sponsored]</p>
</li>
<li>
<p>RedwoodJS is launching <a href="https://redwoodjs.com/">RedwoodSDK</a>, a new framework that wants to become the foundation for “the personal software revolution” – which is like the Sexual Revolution of the ’60s for people who spend way too much time on Discord.</p>
</li>
<li>
<p><a href="https://blog.cloudflare.com/welcome-to-developer-week-2025/">Cloudflare Developer Week 2025</a> just kicked off and I wonder if they’ll mention AI stuff at all.</p>
</li>
<li>
<p>Speaking of which, Cognition Labs just released <a href="https://cognition.ai/blog/devin-2">Devin 2.0</a>, and it promises to <del>take your job twice as hard as last time</del> provide a cool new agent-native IDE experience.</p>
</li>
<li>
<p><a href="https://carbonqa.com/?utm_source=bytes&amp;utm_medium=email&amp;utm_campaign=cool_bits&amp;utm_content=apr7">CarbonQA</a> provides QA services for dev teams, so you’ll never have to QA test your own app ever again. They work in your tools, talk with your team on Slack, and let your engineers spend more of their time <em>engineering</em>. [sponsored]</p>
</li>
<li>
<p>The bolt.new crew have lost their minds and are 1. putting on the world’s biggest hackathon and 2. hosting a “kickoff party” with <a href="https://open.spotify.com/artist/69GGBxA162lTqCwzJG5jLp">The Chainsmokers</a>. Assuming you can get over your social anxiety, <a href="https://concert.hackathon.dev/?live=1">join the waitlist</a> to (potentially) get an invite.</p>
</li>
<li>
<p>Laravel just released <a href="https://laravel-news.com/laravel-wayfinder-public-beta">its first beta of Laravel Wayfinder</a>, a new first-party package that bridges your routes between frontend and backend “with zero friction.”</p>
</li>
<li>
<p><a href="https://github.com/L-Blondy/up-fetch">upfetch</a> is an advanced fetch client builder for TypeScript, which is almost as cool as their other project, <code>updog</code>.</p>
</li>
</ol></div></body></html>]]></content:encoded></item><item><title><![CDATA[The State of the Vuenion]]></title><description><![CDATA[WebKit cat movies, request header fan fic, and what it feels like to be lighter than a React button.]]></description><link>https://bytes.dev/archives/381</link><guid isPermaLink="false">381</guid><pubDate>Thu, 03 Apr 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> WebKit cat movies, request header fan fic, and what it feels like to be lighter than a React button.</p>
<p>Welcome to <a href="https://bytes.dev/archives/381">#381</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/gumbi-president.jpg" alt="Gumbi giving a presidential speech" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">We choose to upgrade to Vue 3 not because it is easy, but because we were promised it would be easy </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>The State of the Vuenion</h3><p>The <a href="https://www.monterail.com/stateofvue">State of Vue.js 2025 Report</a> just came out, and I was relieved to see that Evan You has <em>not</em> imposed any reciprocal tariffs on the React ecosystem <span role="img" aria-label="folded hands">🙏</span>.</p><p>But it turns out there is a lot more happening in Vue-land these days than meets the eye. Let’s break down the good, the bad, and the surprising:</p><p><strong>Vue 3 adoption is going great.</strong> After a harder-than-expected migration from Vue 2, 96% of survey takers say that they’ve used Vue 3 in a project in the last 12 months. And Vue 3 seems to be making good on its promise of improving performance (it’s 55% faster) and providing powerful new features that developers actually use. And yet…</p><p><strong>Vue 3 adoption also isn’t going that great.</strong> The Vue 3 migration was still voted the #1 pain point in the Vue ecosystem by a wide margin, and 35% of survey takers admitted to still using Vue 2 in the last year. That’s nothing to be ashamed of, but it’s less than ideal, considering that Vue 2 hit EOL over 15 months ago and is no longer getting security updates.</p><p><strong>Pinia has taken over state management.</strong> Over 80% of Vue developers now report using Pinia for global state management, which has firmly taken the crown from the previously dominant Vuex library. Pinia’s simple DX, greater type safety, and more modular approach has been a big W for the Vue crew.</p><p><strong>Perf is improving but still needs work.</strong> Vue 3 helped address some of the framework’s performance issues, but there’s definitely still room for improvement. Developers report getting most frustrated when using Vue in large TypeScript codebases and applications with a lot of reactivity. Which brings us to our last point…</p><p><strong>The future of Vue is <del>Vaporware</del> Vapor Mode.</strong> This <a href="https://youtu.be/zvjOT7NHl4Q?t=622">new compilation strategy</a> and runtime is expected to launch (experimentally) in Vue 3.6. It allows you to use the same API and write your Vue code the same way, but the Vue compiler will compile it differently for various compilation outputs. The Vue team expects this to dramatically improve rendering performance and decrease memory usage – but they’re wisely prioritizing compatibility over everything else, so they’re going slow and steady with the implementation.</p><p><strong>Bottom Line:</strong> The Vue vibes are still going strong after 10 years, and with Vapor Mode, Evan You says he wants to prove that “we can introduce significant internal changes and innovation without a big breakage again.” Hopefully, we’ll be able to say the same thing about the world economy 6 months from now.</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/381" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F381" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=Checking%20in%20on%20the%20Vue%20vibes%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F381" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0AChecking%20in%20on%20the%20Vue%20vibes%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F381" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/augment-code-logo.png" alt="augment code logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/rupaul-coding.jpg" alt="Ru Paul looking nervously at a computer" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">When I try to vibe code at my real job </p></div><h3><a href="https://fnf.dev/3FkaGqz">The first AI Agent for large codebases</a></h3><p>Which means you can actually use it at <em>your real job,</em> instead of just for vibe-coding side projects.</p><p>Augment is available in VS Code and JetBrains, and its <a href="https://fnf.dev/4cggCgJ">Context Engine</a> analyzes your entire codebase in real time, so that all of its recommendations have proper context.</p><p>That’s how it ranks #1 in various AI code quality benchmarks, while also providing multi-file edits, full PR creation, and other cool features:</p><ul>
<li>
<p><strong>Persistent Memory</strong> helps it learn your coding style, remember your previous refactors, and adjust to your infra over time.</p>
</li>
<li>
<p><strong>Integrated workflows</strong> with GitHub, Jira, and <a href="https://fnf.dev/4hZFj2b">100+ MCP tools</a> let you go from ticket <span role="img" aria-label="right arrow">➡️</span> code <span role="img" aria-label="right arrow">➡️</span> PR without switching tools.</p>
</li>
<li>
<p><strong>Visual debugging</strong> lets you <a href="https://fnf.dev/4jj1HEY">drag in a screenshot</a>, then have Augment identify all the UI issues, suggest fixes, and run the relevant tests.</p>
</li>
</ul><p><a href="https://fnf.dev/3FkaGqz">Try out the developer plan for free</a> – it comes with all the features and <em>unlimited usage</em>, no credits required.</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://apryse.com/capabilities/page-manipulation?utm_source=bytes.dev&amp;utm_medium=newsletter&amp;utm_campaign=20250403">Apryse</a></h4><p><em>Their advanced <a href="https://apryse.com/capabilities/page-manipulation?utm_source=bytes.dev&amp;utm_medium=newsletter&amp;utm_campaign=20250403">PDF manipulation library</a> lets you easily embed best-in-class document editing into your web, mobile, and desktop applications.</em></p></div></div>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">reduceLanguages</span> <span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> lang<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>languages<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>str<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lang<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>str<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lang<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> user <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Tyler"</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">27</span><span class="token punctuation">,</span>
  <span class="token literal-property property">languages</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"JavaScript"</span><span class="token punctuation">,</span> <span class="token string">"Ruby"</span><span class="token punctuation">,</span> <span class="token string">"Python"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token function">greet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> hello <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, my name is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and I know</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

    <span class="token keyword">const</span> langs <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>languages<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>reduceLanguages<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> hello <span class="token operator">+</span> langs<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> greeting <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">greet</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p>The Safari team just unveiled <a href="https://webkit.org/blog/16587/item-flow-part-1-a-new-unified-concept-for-layout/">Item Flow</a>, a new concept for layout that would incorporate Grid, Masonry, and Flexbox into one unified set of properties. I’m told it has nothing to do with that creepy cat movie that won the Best Animated Film Oscar.</p>
</li>
<li>
<p>Datadog created this <a href="https://www.datadoghq.com/resources/digital-experience-monitoring-solution-brief/?utm_source=bytesdev&amp;utm_medium=newsletter&amp;utm_campaign=dg-apm-ww-dem-brief-bytes">Digital Experience Monitoring Solution Brief</a>, which shows you how to use Datadog as the single source of truth for all your frontend monitoring data – and simplify how your team runs tests and fixes issues. [sponsored]</p>
</li>
<li>
<p><a href="https://astro.build/blog/astro-560/">Astro 5.6</a> comes with a bunch of improved Cloudflare integrations because they’re probably getting acquired soon or something.</p>
</li>
<li>
<p>Lean Rada wrote about <a href="https://leanrada.com/notes/css-only-lqip/">how to create minimal, CSS-only blurry image placeholders</a>.</p>
</li>
<li>
<p><a href="https://nuejs.org/docs/">Nue</a> is a “standards-first” framework with a Don Draper-inspired catch phrase: “Apps lighter than a React button.” Body shaming is not a victimless crime, but we’ll let it slide this time.</p>
</li>
<li>
<p>Mat Biilmann wrote about <a href="https://biilmann.blog/articles/10-years-of-netlify/">10 years of Netlify</a>, and once again tries to teach us all what Jamstack means.</p>
</li>
<li>
<p><a href="https://animejs.com/">Anime.js just released v4 of its animation library</a> with a new modular API, big perf upgrades, scroll-linked animations, and lots more.</p>
</li>
<li>
<p>Alex MacArthur wrote about <a href="https://macarthur.me/posts/forbidden-request-headers/">Forbidden Request Headers</a>, which I know sounds like Harry Potter + web dev fan-fic, but sadly it is not.</p>
</li>
</ol>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug: Solution</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://apryse.com/capabilities/page-manipulation?utm_source=bytes.dev&amp;utm_medium=newsletter&amp;utm_campaign=20250403">Apryse</a></h4></div></div>
<p>If you run the original code, you’ll get “Uncaught TypeError: Cannot read properties of undefined (reading ‘length’)“. The only place we’re using <code>.length</code> is inside our <code>reduceLanguages</code> function, so we can infer that <code>this.languages</code> is <code>undefined</code> and we’re incorrectly using the <code>this</code> keyword.</p>
<p>Whenever you’re trying to figure out what the <code>this</code> keyword is referencing, you need to look at where the function using the <code>this</code> keyword is being invoked. In our example, we don’t know since it’s in the implementation of <code>reduce</code>. To make sure <code>reduceLanguages</code> gets invoked in the right context and therefore has the correct <code>this</code> binding, we have two choices. First, the old school way - using <code>.bind</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token function">greet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> hello <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, my name is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and I know</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> langs <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>languages<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token function">reduceLanguages</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> hello <span class="token operator">+</span> langs<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>Second, the better way - using an arrow function.</p>
<pre class="language-js"><code class="language-js"><span class="token function">greet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> hello <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, my name is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and I know</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> langs <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>languages<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> lang<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>languages<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>str<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lang<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>str<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lang<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>   
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> hello <span class="token operator">+</span> langs<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>The reason this works is because with arrow functions, <code>this</code> is determined <em>lexically</em>. Arrow functions don’t have their own <code>this</code>. Instead, just like with variable lookups, the JavaScript interpreter will look to the enclosing (parent) scope to determine what <code>this</code> should reference.</p></div></body></html>]]></content:encoded></item><item><title><![CDATA[Firefox is finally adding PWA support]]></title><description><![CDATA[JavaScript's mark of the beast, diesel-powered linters, and React 19's best Tim Robinson impersonation.]]></description><link>https://bytes.dev/archives/380</link><guid isPermaLink="false">380</guid><pubDate>Mon, 31 Mar 2025 00:00:00 GMT</pubDate><content:encoded><![CDATA[<html><head></head><body><div style="max-width:600px;padding-top:80px"><p><strong>Today’s issue:</strong> JavaScript’s mark of the beast, diesel-powered linters, and React 19’s best Tim Robinson impersonation.</p>
<p>Welcome to <a href="https://bytes.dev/archives/380">#380</a>.</p>
<div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/lying-awake.jpg" alt="Cartoon character lying awake in bed" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Me thinking about that PWA caching bug that took out my site in 2016 </p></div><hr><div style="text-align:center;margin-bottom:36px"><img width="80" src="https://bytes.dev/images/content/eyes.png" alt="Eyeballs logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">The Main Thing</h2></div><h3>Firefox is finally adding PWA support</h3><p>If you’ve ever managed a successful software product, you know how important it is to get good at ignoring user feedback.</p><p>Firefox has long been the gold standard here, but they might need to give up their crown – because after years of ignoring requests to add support for Progressive Web Apps, it looks like they’re finally giving in.</p><p>They recently added an experimental flag for <code>browser.taskbarTabs.enabled</code> to Firefox Nightly. It doesn’t actually do anything yet, but <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1915736">Taskbar Tabs</a> is Firefox’s fancy name for their PWA-like implementation – which means we should be getting that functionality soon.</p><p>But Firefox isn’t like other <del>girls</del> <em>browsers.</em> So it’s choosing to forego Chrome’s official <a href="https://web.dev/explore/progressive-web-apps">PWA spec</a> and support PWAs in its own cool-and-quirky way:</p><ul>
<li>
<p>Unlike Chromium-based browsers, Firefox web apps will retain key browser UI elements, including the main toolbar and address bar.</p>
</li>
<li>
<p>Users can transition any tab into a web app mode temporarily, without needing to log in again.</p>
</li>
<li>
<p>Installed web apps get their own taskbar/dock icons – and opening a link to one (like Twitter) will launch it <em>in</em> the app, instead of hijacking your main browser window.</p>
</li>
</ul><p><strong>Why deviate from the PWA spec?</strong> It depends on who you ask. <a href="https://www.omgubuntu.co.uk/2025/03/firefox-nightly-supports-web-apps-taskbar-tabs">According</a> to the Firefox team, it’s because they want to “offer features that help you get a more app-like experience for any website you choose,” while still maintaining that “web apps are still websites in a web browser.”</p><p>But critics have argued that Firefox’s proposed implementation looks like a half-hearted attempt to ship something, years after most developers have stopped caring about PWAs.</p><p><strong>Bottom Line:</strong> Firefox and Mozilla might’ve finally changed their tune on PWAs, but at least we can rest easy knowing that they’ll never switch their stance on privacy. Wait.</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;text-align:center;margin-top:40px"><tbody><tr><td style="padding-top:12px"><a href="https://facebook.com/sharer/sharer.php?u=https://bytes.dev/archives/380" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/fb-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fbytes.dev%2Farchives%2F380" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/li-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="https://twitter.com/intent/tweet/?text=Remember%20PWAs%3F%20Well%2C%20Firefox%20decided%20to%20maybe%20start%20supporting%20them%20soon.%0A%0A&amp;url=https%3A%2F%2Fbytes.dev%2Farchives%2F380" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/tw-share-icon.png"></a><span>&nbsp;&nbsp;</span><a href="mailto:?subject=You%20like%20cornbread%3F&amp;body=Thought%20you'd%20love%20this%20week's%20Bytes%0A---%0ARemember%20PWAs%3F%20Well%2C%20Firefox%20decided%20to%20maybe%20start%20supporting%20them%20soon.%0Ahttps%3A%2F%2Fbytes.dev%2Farchives%2F380" rel="noopener" style="text-decoration:none" target="_blank"><img alt="" style="display:inline-block;width:32px" width="25" src="https://bytes.dev/images/em-share-icon.png"></a><span>&nbsp;&nbsp;</span></td></tr></tbody></table>
<hr><div style="text-align:center;margin-bottom:36px"><img width="150" src="https://bytes.dev/images/content/qa-wolf-logo.png" alt="QA Wolf logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px"><span>Our Friends <br class="mobile-break">(With Benefits)</span></h2></div><div class="bg-alt" style="padding:24px;padding-bottom:12px;border-radius:16px;margin-bottom:40px;max-width:100%"><img src="https://bytes.dev/images/content/dog-wall.jpg" alt="A dog sitting on a wall looking at the water" width="600" style="max-width:100%;border-radius:5px"><p style="text-align:center;font-size:15px;line-height:1;padding-top:10px;padding-bottom:4px;margin:0;font-style:italic">Watching my team wait on flaky tests instead of shipping features </p></div><h3><a href="https://www.qawolf.com?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_CutReleaseTime_20250331-None_Experiment-FALSE&amp;utm_term=headline-CutYourTeamsReleaseTimeInHalfWithQAWolf&amp;utm_content=CutReleaseTime_GetAPersonalizedDemo__Headline%3ACutYourTeamsReleaseTimeInHalfWithQAWolf____Newsletter-PrimaryPlacement_20250331_v1_">Cut your team’s release time in half with QA Wolf</a></h3><p>They helped Brilliant reduce their QA cycles from 24 hours to 5 minutes – while providing the equivalent testing capacity of 5 full-time QA engineers (<a href="https://www.qawolf.com/case-studies/brilliant?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_CutReleaseTime_20250331-None_Experiment-FALSE&amp;utm_term=body-SeeTheCaseStudy&amp;utm_content=CutReleaseTime_GetAPersonalizedDemo__Headline%3ACutYourTeamsReleaseTimeInHalfWithQAWolf____Newsletter-PrimaryPlacement_20250331_v1_">see the case study</a>).</p><p>And they’ve done the same for hundreds of other customers. Here’s how:</p><ul>
<li>
<p>They create, maintain, and <a href="https://www.qawolf.com/how-it-works?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_CutReleaseTime_20250331-None_Experiment-FALSE&amp;utm_term=body-RunPlaywrightTests&amp;utm_content=CutReleaseTime_GetAPersonalizedDemo__Headline%3ACutYourTeamsReleaseTimeInHalfWithQAWolf____Newsletter-PrimaryPlacement_20250331_v1_">run Playwright tests</a> to cover your entire application</p>
</li>
<li>
<p>They get you pass/fail results within 3 min and provide unlimited parallel test runs on their infrastructure.</p>
</li>
<li>
<p>Every failed test is reviewed by their team of <a href="https://www.qawolf.com/how-it-works?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_CutReleaseTime_20250331-None_Experiment-FALSE&amp;utm_term=body-HumanQAEngineers&amp;utm_content=CutReleaseTime_GetAPersonalizedDemo__Headline%3ACutYourTeamsReleaseTimeInHalfWithQAWolf____Newsletter-PrimaryPlacement_20250331_v1_">human QA engineers</a>, so you get zero flakes.</p>
</li>
</ul><p>Their customers save 9 hours/week <em>per engineer</em> on average – and 90% of customers eliminate post-release hot fixes.</p><p><a href="https://www.qawolf.com?utm_source=bytes&amp;utm_medium=newsletter&amp;utm_campaign=ACQ_All_Demo_Conversions__NewsletterAudience_-_Newsletter_CutReleaseTime_20250331-None_Experiment-FALSE&amp;utm_term=cta-GetAPersonalizedDemo&amp;utm_content=CutReleaseTime_GetAPersonalizedDemo__Headline%3ACutYourTeamsReleaseTimeInHalfWithQAWolf____Newsletter-PrimaryPlacement_20250331_v1_">Get a personalized demo</a> – and start speeding up your team’s releases.</p>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://query.gg/">query.gg</a></h4><p><em>Does your team use React Query? If so, check out <a href="https://query.gg/">query.gg</a> and see why managers at LinkedIn and Broadcom use it to train their engineers.</em></p></div></div>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">eventuallyFail</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">throw</span> <span class="token function">Error</span><span class="token punctuation">(</span><span class="token string">"Oops!"</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> time<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">try</span> <span class="token punctuation">{</span>
  <span class="token function">eventuallyFail</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>message<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/cool-bits.png" alt="Cool Bits logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Cool Bits</h2></div><ol>
<li>
<p><a href="https://github.com/facebook/react/releases/tag/v19.1.0">React 19.1</a> just dropped, and it introduces “Owner Stacks” – a development-only stack trace that identifies which components are responsible for rendering a particular component that led to an error. “We’re all looking for the guy who did this.”</p>
</li>
<li>
<p>Jacob Voytko wrote about <a href="https://www.clientserver.dev/p/war-story-the-hardest-bug-i-ever">the hardest bug he ever debugged</a> while on the Google Docs team.</p>
</li>
<li>
<p>Kyle Gill took a science-based approach to answer the question humans have been asking themselves ever since they first gazed up at the stars: <a href="https://www.kylegill.com/essays/vite-vs-turbopack/">Is Vite faster than Turbopack?</a></p>
</li>
<li>
<p>Mahesh Murag from Anthropic gave this 2-hour workshop on <a href="https://www.youtube.com/watch?v=kQmXtrmQ5Zg">building agents with MCP</a> at the AI Engineer Summit.</p>
</li>
<li>
<p>TypeScript maintainer, Josh Goldberg wrote about how <a href="https://www.joshuakgoldberg.com/blog/hybrid-linters-the-best-of-both-worlds/">Hybrid Linters are the best of both worlds</a>. When will these tech hippies learn that some of us just prefer our diesel-powered linters?</p>
</li>
<li>
<p><a href="https://rspack.dev/blog/announcing-1-3?123">Rspack v1.3</a> comes with circular dependency detection, build HTTP imports, and lots of perf upgrades.</p>
</li>
<li>
<p>The V8 team wrote about <a href="https://v8.dev/blog/leaving-the-sea-of-nodes">why they decided to move away from Sea of Nodes</a>. I figured it was because of all the people who disappeared at that old lighthouse, but it turns out it was just the high HOA fees.</p>
</li>
<li>
<p><a href="https://blogs.windows.com/windowsdeveloper/2025/03/27/announcing-babylon-js-8-0/">Babylon.js just released v8.0</a> of their open web rendering engine, with Image-Based Lighting shadows and lots more.</p>
</li>
<li>
<p>The Netlify team wrote a totally unbiased article called <a href="https://www.netlify.com/blog/how-we-run-nextjs/">How we run Next.js today – and why Vercel’s triangle logo is the Mark of the Beast that John warned us about in Revelation</a>.</p>
</li>
</ol>
<hr><div style="text-align:center;margin-bottom:36px"><img width="110" src="https://bytes.dev/images/content/spot-the-bug.png" alt="Spot the Bug logo"><h2 style="font-family:Paytone One, sans-serif;text-transform:uppercase;font-size:28px">Spot the Bug: Solution</h2><div class="section-presenter" style="margin-bottom:50px;margin-top:15px"><h4>Sponsored by <a href="https://query.gg/">query.gg</a></h4></div></div>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">eventuallyFail</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">throw</span> <span class="token function">Error</span><span class="token punctuation">(</span><span class="token string">"Oops!"</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> time<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">try</span> <span class="token punctuation">{</span>
  <span class="token function">eventuallyFail</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>message<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p><code>try/catch</code> is synchronous. By the time our error is <code>throw</code>n, the <code>try/catch</code> block will be long gone - leaving us with <code>Uncaught Error: Oops!</code>. To fix this, we want to rely on promises which allow us more async control.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">eventuallyFail</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res<span class="token punctuation">,</span> rej</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">rej</span><span class="token punctuation">(</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token string">"Oops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> time<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token function">eventuallyFail</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>reason<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div></body></html>]]></content:encoded></item></channel></rss>