<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sylwia Laskowska</title>
    <description>The latest articles on DEV Community by Sylwia Laskowska (@sylwia-lask).</description>
    <link>https://dev.to/sylwia-lask</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3535771%2Fe22860d5-274b-43c9-819b-56b162e5bd5a.jpeg</url>
      <title>DEV Community: Sylwia Laskowska</title>
      <link>https://dev.to/sylwia-lask</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sylwia-lask"/>
    <language>en</language>
    <item>
      <title>The Dirty Secret Behind AI Agents (Demo 🚀)</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Thu, 23 Jul 2026 07:03:51 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/the-dirty-secret-behind-ai-agents-demo--273d</link>
      <guid>https://dev.to/sylwia-lask/the-dirty-secret-behind-ai-agents-demo--273d</guid>
      <description>&lt;p&gt;For quite a while now, I've had the feeling that AI agents are surrounded by this mystical aura. Nobody really knows what they're doing, they're probably going to take over the world soon, and if you want to build one yourself... well, obviously you need a framework.&lt;/p&gt;

&lt;p&gt;What if I told you that's not true? You can build your own AI agent in about 80 lines of code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have to admit, this week hasn't been easy. A lot has been happening at work. On top of that, I received an automatic rejection email for one of my CFPs. Normally, that would have occupied my mind for maybe five minutes, because conference rejections are just part of the game.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Except... I had actually been &lt;strong&gt;INVITED&lt;/strong&gt; to that conference. "You're already accepted, just need to collect the talk details in CFP." Because of that invitation, I turned down two other conference opportunities. Oh well. At least I have September free now.😉&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anyway, life goes on. Today is my birthday, so as a little gift from me to myself (and to all of you!), I wrote this article. 😄 I hope you'll enjoy it!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do We Really Need a Framework?
&lt;/h2&gt;

&lt;p&gt;Let's get to the point.&lt;/p&gt;

&lt;p&gt;Frameworks like LangChain, CrewAI, or Mastra aren't doing magic. They simplify things like conversation memory, tool execution, retries, fallbacks, etc.&lt;/p&gt;

&lt;p&gt;Once you understand the underlying mechanism, it becomes much easier to decide when a framework is actually worth using. And even if you end up using one anyway, you'll understand what's happening under the hood. &lt;/p&gt;

&lt;p&gt;So I decided to build a small demo and see how little code an AI agent actually needs.&lt;/p&gt;

&lt;p&gt;I wrote an AI agent in Node.js in roughly &lt;strong&gt;80 lines of code&lt;/strong&gt;... okay, okay, the &lt;strong&gt;core loop&lt;/strong&gt; is about 80 lines. There are still tools, a provider abstraction, and a bit of surrounding logic. But come on, &lt;em&gt;"an AI agent in 80 lines"&lt;/em&gt; sounds much better. 😄&lt;/p&gt;

&lt;p&gt;Here's the repository:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/sylwia-lask/code-review-agent" rel="noopener noreferrer"&gt;https://github.com/sylwia-lask/code-review-agent&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And since it's my birthday... if you enjoy the project, feel free to give it a ⭐. Only if you actually like it, of course. 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet Steve
&lt;/h2&gt;

&lt;p&gt;The application is a simple code review agent. Well... not exactly.&lt;/p&gt;

&lt;p&gt;Meet &lt;strong&gt;Steve&lt;/strong&gt;: a software engineer with 15 years of experience reviewing other people's code. Steve doesn't take anything at face value. Sure, he can be a little sarcastic sometimes... but it's hard to argue with his conclusions.&lt;/p&gt;

&lt;p&gt;Here's what one of his code reviews looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdfydb5wavs15jzt8krqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdfydb5wavs15jzt8krqg.png" alt="Steve's agent code review" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze4eklyq11qlo7kgg1d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze4eklyq11qlo7kgg1d3.png" alt="Steve's agent code review - part 2" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or when you have empty diff: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhqbe2cwceh41qufmv2ws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhqbe2cwceh41qufmv2ws.png" alt="Review with empty diff" width="798" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For now, Steve reviews the local Git diff. Which basically means... he's reviewing &lt;strong&gt;himself&lt;/strong&gt;. So I guess I've built a prototype of the famous self-healing agent that, according to &lt;a class="mentioned-user" href="https://dev.to/nitsancohen770"&gt;@nitsancohen770&lt;/a&gt;, is going to take my job one day.&lt;/p&gt;

&lt;p&gt;As you can see, I'm basically helping automate myself out of employment. Maybe it's finally time to start thinking about retirement. 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  "An Agent Is Just a While Loop"
&lt;/h2&gt;

&lt;p&gt;In my previous article, I joked about people claiming that an AI agent is nothing more than a &lt;code&gt;while&lt;/code&gt; loop. Well... Mine isn't even a &lt;code&gt;while&lt;/code&gt; loop. It's a &lt;code&gt;for&lt;/code&gt; loop, because I wanted to protect myself from accidentally creating an infinite loop and loosing too much money on tokens. 😄&lt;/p&gt;

&lt;p&gt;Okay, to be fair, the loop itself doesn't actually &lt;em&gt;do&lt;/em&gt; anything. It's simply responsible for orchestrating the process. But the funny part is that most agent frameworks are doing something remarkably similar under the hood.&lt;/p&gt;

&lt;p&gt;The loop itself was trivial to write. The real challenge was exactly where you'd expect it to be.&lt;/p&gt;

&lt;p&gt;Building an AI agent starts with... choosing an LLM. 😄 This time I picked the Gemini API because tokens for projects like this are ridiculously cheap. I'm definitely tempted to build the next version using a local model, but... hold on. 😄&lt;/p&gt;

&lt;p&gt;I immediately ran into one issue: some Gemini models were overloaded, so I kept getting &lt;strong&gt;503&lt;/strong&gt; responses. That meant I had to implement something frameworks usually provide out of the box — a simple retry mechanism.&lt;/p&gt;

&lt;p&gt;Mine is intentionally very basic. Production frameworks usually offer much more, like exponential backoff, jitter, or automatic fallback to another model.&lt;/p&gt;

&lt;p&gt;The next challenge was, of course, writing the right prompt. After that, everything became surprisingly straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does the Agent Actually Work?
&lt;/h2&gt;

&lt;p&gt;It's much simpler than you might think.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1:  Send the prompt and available tools
&lt;/h3&gt;

&lt;p&gt;We send two things to the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user's message,&lt;/li&gt;
&lt;li&gt;the list of tools the model is allowed to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what the request looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-2.5-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"contents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Please review the current git diff."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"systemInstruction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You are Steve, a senior software engineer with 15 years of experience..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"functionDeclarations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getDiff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Get the git diff of the current repository..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OBJECT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getFile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Read a file from the repository..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OBJECT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STRING"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Path to the file relative to the repository root"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"listFiles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"List files and directories at a given path..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OBJECT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STRING"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Directory path relative to the repository root"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Wait for the model's response
&lt;/h3&gt;

&lt;p&gt;The model can respond in one of three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;with plain text,&lt;/li&gt;
&lt;li&gt;by requesting a tool call,&lt;/li&gt;
&lt;li&gt;or with both.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it returns plain text, we're done: that's our final code review. If it asks us to call a tool, we move on to Step 3.&lt;/p&gt;

&lt;p&gt;For example, we might receive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"candidates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Let's see what damage we're dealing with today..."&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"functionCall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"call_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getDiff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Execute the tool locally
&lt;/h3&gt;

&lt;p&gt;Now it's our application's turn.&lt;/p&gt;

&lt;p&gt;We execute the requested tool locally. For example, running &lt;code&gt;git diff&lt;/code&gt; or reading a file from the repository, and send the result back to the model &lt;strong&gt;as another message in the conversation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The tools available in this demo are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getDiff&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getFile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;listFiles&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, everything a good code reviewer needs. 😄&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Repeat until the model is done
&lt;/h3&gt;

&lt;p&gt;Then we simply go back to Step 2. To avoid getting stuck in an infinite loop, I limit the maximum number of iterations to &lt;strong&gt;10&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There's one more important detail, though.&lt;/p&gt;

&lt;p&gt;Take a look at the next request. Notice that we're sending the &lt;strong&gt;entire conversation history&lt;/strong&gt; back to the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"contents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Please review the current git diff."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Let's see what damage we're dealing with today..."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"functionCall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"call_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getDiff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"functionResponse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"call_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getDiff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"diff --git a/src/auth.ts b/src/auth.ts&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;--- a/src/auth.ts&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;+++ b/src/auth.ts&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;@@ -12,7 +12,7 @@&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;-  if (password === storedHash) {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;+  if (password == storedHash) {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And... that's it. The LLM decides &lt;strong&gt;which tool to use&lt;/strong&gt; and &lt;strong&gt;when it's done&lt;/strong&gt;. Everything else — executing the tools, handling retries, enforcing iteration limits, and orchestrating the loop — is the responsibility of our application.&lt;/p&gt;

&lt;p&gt;Simple, isn't it? If you like visualisations, ChatGPT prepared one for us 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmzwfwpipz593yrikngg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmzwfwpipz593yrikngg5.png" alt="Visualisation of how agent works" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;I'd like to write at least two follow-up articles in the future. One about connecting Steve to &lt;strong&gt;MCP&lt;/strong&gt;, and another about replacing the hosted model with a &lt;strong&gt;local LLM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But... hold on. One step at a time. 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: How does the model know it should call a function?
&lt;/h2&gt;

&lt;p&gt;If you only came here to learn how to build an AI agent, you can probably stop reading now. 😄&lt;/p&gt;

&lt;p&gt;This section is for the curious ones. Because sooner or later, someone is going to ask: &lt;em&gt;"Sylwia, what are you talking about? You say you're building your own AI agent, but you're just using the Gemini SDK. You send it JSON, you get JSON back."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And, as &lt;a class="mentioned-user" href="https://dev.to/darkwiiplayer"&gt;@darkwiiplayer&lt;/a&gt; often points out, an LLM is basically a very sophisticated next-token predictor, not some magical JSON generator.&lt;/p&gt;

&lt;p&gt;So... How does the model know what to do when we send it JSON? What would happen if, instead of Gemini, we used some old local Llama model?&lt;/p&gt;

&lt;p&gt;Does the Gemini SDK secretly prepend some special prompt? Or are the models themselves trained for this?&lt;/p&gt;

&lt;p&gt;The honest answer is that we don't know all the details. What we &lt;em&gt;do&lt;/em&gt; know is that models like &lt;strong&gt;Gemini&lt;/strong&gt; and &lt;strong&gt;GPT&lt;/strong&gt; have native support for tool calling. The SDK is responsible for formatting requests correctly and communicating with the API, while the model itself understands tool declarations and can generate function calls when it decides they're needed.&lt;/p&gt;

&lt;p&gt;In other words, if we took an older Llama model, we could still write a prompt explaining how to interpret the JSON and asking it to respond in a specific JSON format.&lt;/p&gt;

&lt;p&gt;Then we'd simply call &lt;code&gt;JSON.parse()&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;...assuming the model actually returns valid JSON instead of Markdown, an explanation, or a few "helpful" comments it decided to add. 😄&lt;/p&gt;

&lt;p&gt;That said, it's worth mentioning that newer open-source models increasingly support tool calling natively as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue: An agent written by another agent
&lt;/h2&gt;

&lt;p&gt;Let's be honest. It's 2026. This agent was written largely by... &lt;strong&gt;another AI agent&lt;/strong&gt;. 😄&lt;/p&gt;

&lt;p&gt;Since I've been an AWS Community Builder for a while now, I cancelled my Claude Code subscription and switched to &lt;strong&gt;Kiro&lt;/strong&gt;: an AI IDE with built-in support for multiple LLMs, including Claude, GPT, and Gemini. It costs about the same, but thanks to the program, I get to use it for free. &lt;/p&gt;

&lt;p&gt;So far, I'm really enjoying it. It feels a bit like an agent-powered layer on top of VS Code, so I immediately felt at home. I also have the feeling that I'm currently using maybe &lt;strong&gt;10%&lt;/strong&gt; of what it can actually do, so I'm pretty sure I'll write more about it in the future.&lt;/p&gt;

&lt;p&gt;Now I'm just hoping AWS will finally send me some swag. 😄 I'm especially dreaming about one of their T-shirts. Years ago, we actually had a political party in Poland called &lt;strong&gt;AWS&lt;/strong&gt;, so I'd absolutely love to see the expressions on some older people's faces. 😄&lt;/p&gt;

&lt;p&gt;AWS... if you're reading this... I'm waiting!! 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;As you can see, an AI agent doesn't have to start with a framework. Sometimes all you need is an LLM, tools, convarsation history and a simple loop. Everything else is convenience, production hardening, and quality-of-life improvements.&lt;/p&gt;

&lt;p&gt;So...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do you think about Steve? And how do you like this approach to building an AI agent?&lt;/strong&gt; 😄&lt;/p&gt;

&lt;p&gt;If you liked this post you can also follow me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>ai</category>
      <category>agents</category>
      <category>javascript</category>
    </item>
    <item>
      <title>8 Things Developers Confidently Explain After Watching One YouTube Video</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Tue, 14 Jul 2026 17:57:43 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/8-things-developers-confidently-explain-after-watching-one-youtube-video-3jio</link>
      <guid>https://dev.to/sylwia-lask/8-things-developers-confidently-explain-after-watching-one-youtube-video-3jio</guid>
      <description>&lt;p&gt;I just got back from my vacation which, like 99% of Polish people, I spent in Croatia. &lt;strong&gt;Dobar dan!&lt;/strong&gt; 🇭🇷&lt;/p&gt;

&lt;p&gt;I've got a really fun article in my head right now, but it needs a bit of research before I can publish it, so that'll be coming next week. In the meantime, let's do something much lighter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BTW, a small update.&lt;/strong&gt; &lt;em&gt;I said that FrontKon would be my last conference this year... well, apparently I lied. 😂 When&lt;/em&gt; &lt;strong&gt;iJS Munich&lt;/strong&gt; &lt;em&gt;reaches out, you simply don't say no. Especially after looking at the speaker lineup. It's basically a conference full of geniuses... plus me. 😅 So I'll be speaking there at the end of October about&lt;/em&gt; &lt;strong&gt;WebAssembly and WebGPU in React&lt;/strong&gt;, &lt;em&gt;and I'm already ridiculously excited.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you happen to have a spare bag of money lying around xDDD (or, much more realistically, your company still has some training budget left), come and say hi! I'd love to meet some of you in person. 😊&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyway... let's get back to today's topic.&lt;/p&gt;

&lt;p&gt;As many of you probably know, I have a soft spot for LinkedIn gurus and people who explain everything with absolute confidence. You know the type: their solution is always the best one, everyone else is wrong, and there are absolutely no trade-offs. 😄&lt;/p&gt;

&lt;p&gt;Sometimes I get the feeling that at least some of that confidence comes directly from a single 15-minute YouTube tutorial.&lt;/p&gt;

&lt;p&gt;But let's be fair for a second.&amp;nbsp;Who among us hasn't watched a short video, finished it thinking &lt;em&gt;"Yep, I totally understand this now!"&lt;/em&gt;, and then discovered during the actual implementation that reality was... slightly more complicated? 😂&lt;/p&gt;

&lt;p&gt;Since I spend most of my time working with JavaScript and AI agents these days, most examples will probably come from those areas. Feel free to add your own in the comments!&lt;/p&gt;




&lt;h2&gt;
  
  
  1. React / Angular / Vue (cross out the unnecessary one) is the best framework
&lt;/h2&gt;

&lt;p&gt;This is probably the most common opinion after watching an internet guru, especially if you haven't formed your own yet.&lt;/p&gt;

&lt;p&gt;Angular is the best because it has everything.&amp;nbsp;React is the best because everybody uses it.&amp;nbsp;Vue is the best because... well... Vue people will tell you why. 😄&lt;/p&gt;

&lt;p&gt;Then you spend a few years building real projects and suddenly discover that all of these have strengths, weaknesses and different use cases. In the end, the "best framework" is usually just the one that solves &lt;em&gt;your&lt;/em&gt; problem best.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. LLMs are just autocomplete
&lt;/h2&gt;

&lt;p&gt;Or, if you prefer another popular version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"They're just stochastic parrots."&lt;/p&gt;

&lt;p&gt;"They're not creative."&lt;/p&gt;

&lt;p&gt;"They don't really understand anything."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well... if it's all that simple, why do entire teams of researchers and engineers spend years working on them? Why are companies burning through billions of dollars worth of GPUs? 😄&lt;/p&gt;

&lt;p&gt;Another statement that always makes me smile is that LLMs "aren't creative."&amp;nbsp;Sure, they probably won't invent something completely detached from everything humanity has ever known.&lt;/p&gt;

&lt;p&gt;But then again... neither do most humans.&lt;/p&gt;

&lt;p&gt;Most people don't wake up one morning and invent quantum mechanics or write &lt;em&gt;The Lord of the Rings&lt;/em&gt;. Creativity is usually about combining existing ideas in interesting ways, and LLMs are actually surprisingly good at that.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. CQRS (or Redux on the frontend) is easy
&lt;/h2&gt;

&lt;p&gt;Sure.&amp;nbsp;Then you open the codebase and suddenly you're staring into the architectural equivalent of a horror movie.&lt;/p&gt;

&lt;p&gt;I've honestly seen everything.&amp;nbsp;Business logic split between Redux stores and components.&amp;nbsp;Half the state managed globally, the other half locally.&amp;nbsp;Actions that somehow contain business logic.&amp;nbsp;Reducers that apparently decided to become services.&lt;/p&gt;

&lt;p&gt;Years ago, when I was interviewing developers more often, I used to ask a very simple question:&amp;nbsp;&lt;strong&gt;"Why do we actually need CQRS (or Redux)?"&amp;nbsp;&lt;/strong&gt;(By the way... not everyone even knew the difference between the two.)&amp;nbsp;Then I'd ask another one:&amp;nbsp;&lt;strong&gt;"Why can't we solve this in a simpler way?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I swear, a surprising number of people answered something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't know... that's just how people do it."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. AI agents are just a while loop
&lt;/h2&gt;

&lt;p&gt;To be fair!&amp;nbsp;A good friend of mine, and my former tech lead, actually gives an excellent conference talk with exactly this title. It's intentionally provocative.&lt;/p&gt;

&lt;p&gt;And let's face the truth... there is quite a bit of truth to it.&amp;nbsp;Many AI agents really are "just a while loop."&lt;/p&gt;

&lt;p&gt;The funny part starts about three weeks later.&amp;nbsp;Suddenly your tiny little while loop has three MCP servers, an orchestration framework, retries, memory, tool calling, etc, etc...&lt;/p&gt;

&lt;p&gt;Still one of the most fun things I've worked with recently, though.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. WebAssembly is always faster
&lt;/h2&gt;

&lt;p&gt;Whenever someone says this, I always ask the same two questions:&amp;nbsp;&lt;strong&gt;Faster than what&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;And faster at doing what?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't get me wrong, WebAssembly is amazing. There are plenty of scenarios where it absolutely destroys JavaScript performance, especially when you're dealing with computationally intensive algorithms, simulations or similar workloads.&lt;/p&gt;

&lt;p&gt;But if your application spends most of its life waiting for HTTP requests to finish...&amp;nbsp;WebAssembly probably won't make the internet faster.&lt;/p&gt;

&lt;p&gt;And it probably won't suddenly turn your dashboard into NASA software either. 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Unit tests are our golden ticket
&lt;/h2&gt;

&lt;p&gt;Especially the ones generated by the same LLM that just generated the production code. 😂&amp;nbsp;100% confidence!&lt;/p&gt;

&lt;p&gt;Or... maybe not.&lt;/p&gt;

&lt;p&gt;This can be particularly misleading on the frontend, where unit tests often verify exactly the code that was the easiest to write in the first place.&lt;/p&gt;

&lt;p&gt;Congratulations, you've successfully achieved 100% test coverage, and 0% confidence!&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Let's just add RAG
&lt;/h2&gt;

&lt;p&gt;Yeees...&lt;/p&gt;

&lt;p&gt;As if finding, cleaning, maintaining and selecting the right documents was somehow the easy part. 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Microservices / Microfrontends are the only good architecture
&lt;/h2&gt;

&lt;p&gt;Absolutely!&amp;nbsp;Especially if your application consists of six screens and one backend service. 😄&amp;nbsp;Or if you've got a perfectly healthy monolith that everyone on the team understands.&lt;/p&gt;

&lt;p&gt;Sometimes a distributed architecture is exactly what you need.&amp;nbsp;Sometimes it's just distributed complexity.&lt;/p&gt;




&lt;p&gt;I could probably keep going for another twenty examples, but I think that's enough for today. 😂&lt;/p&gt;

&lt;p&gt;What about you?&amp;nbsp;Have you ever met one of those &lt;strong&gt;"one-YouTube-video gurus"&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you enjoyed this article, consider following me also on&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/sylwia-laskowska-5a8467131/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>jokes</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>What's Next for AI?</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Mon, 29 Jun 2026 07:18:48 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/whats-next-for-ai-219i</link>
      <guid>https://dev.to/sylwia-lask/whats-next-for-ai-219i</guid>
      <description>&lt;p&gt;I have been writing about AI for quite a while now, but this is probably the first time I genuinely do not know what to think. Not because the technology has suddenly slowed down, but because the rules of the game may be changing.&lt;/p&gt;

&lt;p&gt;I wanted to write something lighter today, but I feel like I have to share some thoughts from the last few days. It is getting harder and harder to ignore what is happening around the newest AI models. &lt;a class="mentioned-user" href="https://dev.to/pascal_cescato_692b7a8a20"&gt;@pascal_cescato_692b7a8a20&lt;/a&gt;  post, &lt;a href="https://dev.to/pascal_cescato_692b7a8a20/1-15n0"&gt;1%&lt;/a&gt;, only confirmed that I am not the only person wondering what comes next.&lt;/p&gt;

&lt;p&gt;But let’s start from the beginning. Last Friday, well-known technology journalist Adrian Bridgwater asked me for a comment for this article: &lt;a href="https://thenewstack.io/openai-gpt56-access-restricted/?brid=YWdncwEMxBTPiT6ShdbXEYRc5kmt" rel="noopener noreferrer"&gt;OpenAI GPT-5.6 Access Restricted&lt;/a&gt;. As someone who used to work in media, I know exactly what journalists hope for when they ask for a comment: a quick response, a short quote, and one strong punchline. 😅 But this time, the topic made me stop and think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four years that changed everything
&lt;/h2&gt;

&lt;p&gt;In the last few years, the progress of AI has been incredible. We all know that. On November 30, 2022, OpenAI released ChatGPT, based on GPT-3.5, and generative AI suddenly became mainstream. It took only a few months, and by January 2023 ChatGPT had already reached around 100 million monthly users.&lt;/p&gt;

&lt;p&gt;Even then, people were saying that AI would soon take jobs away from developers. And yet, from today’s perspective, less than four years later, GPT-3.5 almost feels dumb.&lt;/p&gt;

&lt;p&gt;A year later, we were all laughing at vibe coders and contrasting them with REAL software engineers. But then coding agents arrived, and suddenly we all became vibe coders 😉 Okay, we all know that Claude Code or similar tools still will not replace a good developer today, and AI adoption inside companies often leaves a lot to be desired.&lt;/p&gt;

&lt;p&gt;But this is still less than four years of LLMs being truly available on the market. What if, in another two or four years, agents really are good enough to write code much better than humans? Where is the limit of this technology?&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do developers fit in?
&lt;/h2&gt;

&lt;p&gt;I have to admit, I am a typical overthinker. I love analyzing the world and people, and thinking two hundred steps ahead. Of course, developers would still be needed in such a world, but would all of us be needed? Or would a company that used to need 500 engineers suddenly need five? Or just a small group of people training, supervising, and integrating models?&lt;/p&gt;

&lt;p&gt;I am a solid senior engineer, and my market advantage is that apart from writing code, I can talk to people. And business desperately needs that. But I am not the kind of person who will lock herself in a basement for a month and dig deep into hardware internals to make LLMs run faster. I am also not someone who will happily spend 12 hours a day in silence working on benchmarks. I admire people like that, but that is definitely not me.&lt;/p&gt;

&lt;p&gt;And I am not sure that if LLMs developed much further, my advantage of “being able to talk to business” would still be an advantage at all. So what should I do? Maybe slowly start looking toward developer advocacy, since that seems to be going well for me? Maybe send my CV to the nearby Biedronka discount store just in case — they are actually hiring, and I am there every day anyway, sometimes guiding people to products better than the staff 😆&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes, changes...
&lt;/h2&gt;

&lt;p&gt;But then something started to change. Tokens became much more expensive. Companies started realizing that maybe, for simple tasks, a junior developer might actually make more sense 😅 And seriously, I do not yet see a massive wave of hiring interns, but saving tokens, giving up certain tools, and saying “use a cheaper model for simple tasks” has become very common.&lt;/p&gt;

&lt;p&gt;And now there is the embargo. First around Mythos and Fable, and now around GPT-5.6. If you missed it, the short version is that access to some of the most advanced AI models is no longer simply “available to everyone who can pay.” It is becoming restricted, limited by geography, organization type, security concerns, or strategic decisions. In practice, this means that not every developer, company, or country can count on equal access to the best models anymore.&lt;/p&gt;

&lt;p&gt;I do not know what to think about this. Are these models really so dangerous for critical infrastructure? &lt;/p&gt;

&lt;p&gt;Or maybe governments have simply started treating them as a strategic asset, similar to semiconductors? Maybe this is the end of the free AI market?&lt;/p&gt;

&lt;p&gt;For developers, at first, it probably will not matter that much. Even if LLM progress stopped at the models we already have today, we would still improve the infrastructure, polish the agents, build better tooling, and continue working quite happily. Maybe for some time the models would even become more stable, with more reliable APIs and better developer experience.&lt;/p&gt;

&lt;p&gt;But what happens next? Will working with powerful LLMs be reserved only for selected people? Or selected companies? Or selected countries?&lt;/p&gt;

&lt;p&gt;On the other hand... these models are ridiculously expensive. Somebody has to pay for them. It is difficult for me to imagine companies investing billions only to keep their best models locked in a vault forever. They need customers. They need revenue. So maybe this whole "AI embargo" is only temporary? Or maybe governments will eventually step in and treat frontier AI the way they treat strategic infrastructure? Honestly, I have no idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  So... what happens next?
&lt;/h2&gt;

&lt;p&gt;Maybe it will be like Polish sci-fi writer Rafał Kosik predicted 20 years ago in his young adult series Felix, Net and Nika — AI will become unavailable to the public because it will be considered too dangerous, and models will be kept locked away? 😉 Of course, this is an extreme vision, but honestly, nothing surprises me anymore.&lt;/p&gt;

&lt;p&gt;Just a year or two ago, we were asking whether AI would replace developers. Today I find myself wondering about something slightly different: will the most powerful AI even remain available to ordinary people?&lt;/p&gt;

&lt;p&gt;What do you think? Where is all of this going? I do not want to pretend to be an all-knowing sheriff here, and I am genuinely curious about your perspective.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also, I will not publish anything next week because I am going on vacation — like every self-respecting Polish person, to Croatia. This is just a note for those of you who read my posts every Sunday around lunchtime 😆&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And if you are from Czechia or somewhere nearby, come to *&lt;/em&gt;&lt;a href="https://www.frontkon.tech/" rel="noopener noreferrer"&gt;FrontKon&lt;/a&gt;*&lt;em&gt;, where I will be speaking. Let’s high-five there!&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Or, if you like, please follow me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>7 New JavaScript Features (And 2 I'm Still Waiting For)</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Wed, 24 Jun 2026 09:14:11 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/7-new-javascript-features-and-2-im-still-waiting-for-2ck8</link>
      <guid>https://dev.to/sylwia-lask/7-new-javascript-features-and-2-im-still-waiting-for-2ck8</guid>
      <description>&lt;p&gt;Remember how I promised you (or rather myself) two weeks ago that from now on I'd only write light, easy posts? Well… I broke that promise 😅 Last week I published a huge article about one of the least sexy topics imaginable: legacy applications. Somehow, despite that, the DEV editorial team liked it enough to include it in the &lt;strong&gt;Top 7 Posts of the Week&lt;/strong&gt; ❤️&lt;/p&gt;

&lt;p&gt;But today is finally the day for something a bit lighter. And I think it's a topic that deserves more attention.&lt;/p&gt;

&lt;p&gt;These days we spend a lot of time talking about AI agents, and I absolutely understand why, because it's a fascinating field. But I sometimes feel we're forgetting that the programming languages we use every day are evolving too.&lt;/p&gt;

&lt;p&gt;I spend most of my days writing JavaScript (well… TypeScript, obviously 😄). And yes, the ecosystem has matured a lot over the last few years. We no longer have endless React vs Angular wars. We're also mostly past those times when everyone loved Redux one month and six months later decided it was an overengineered monster and removed it from every application 😅.&lt;/p&gt;

&lt;p&gt;But both the ecosystem and the ECMAScript standard keep evolving.&lt;/p&gt;

&lt;p&gt;After the legendary ES6 release in 2015, which changed frontend development forever, the TC39 committee switched to an iterative approach and started shipping new features every year.&lt;/p&gt;

&lt;p&gt;And the nice thing is that if you're using modern browsers or runtimes, you often get access to these features almost immediately.&lt;/p&gt;

&lt;p&gt;So, what do we get in &lt;strong&gt;ECMAScript 2026&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Oh, and to keep things entertaining, all code examples in this article are based on the internal monologue of imaginary LinkedIn gurus with very strong opinions. Any resemblance to actual people is, naturally, purely coincidental 😇&lt;/p&gt;

&lt;p&gt;Other articles from this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sylwia-lask/stop-installing-libraries-10-browser-apis-that-already-solve-your-problems-35bi"&gt;Stop Installing Libraries: 10 Browser APIs That Already Solve Your Problems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sylwia-lask/9-things-youre-overengineering-the-browser-already-solved-them-o99"&gt;9 Things You're Overengineering — The Browser Already Solved Them&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sylwia-lask/16-modern-javascript-features-that-might-blow-your-mind-4h5e"&gt;16 Modern JavaScript Features That Might Blow Your Mind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Map.prototype.getOrInsert() / Upsert
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsert" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsert&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of those features that makes you wonder: "Wait… why didn't we have this ten years ago?"&lt;/p&gt;

&lt;p&gt;Imagine we're collecting opinions from LinkedIn gurus. Until now, we had to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opinions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addOpinion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;opinions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;opinions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;opinions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;addOpinion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10x Engineer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;addOpinion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Principal AI Evangelist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but there's quite a bit of boilerplate.&lt;/p&gt;

&lt;p&gt;With ES2026, things become much nicer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opinions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;opinions&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOrInsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10x Engineer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;opinions&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOrInsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Principal AI Evangelist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We also get a computed version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opinions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;opinions&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOrInsertComputed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nobody writes clean code anymore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DDD Purist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Come on, that's so much cleaner and easier to read. It's also perfect for caching! Much less code, much nicer API.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Iterator.concat()
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/concat" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/concat&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we talk about &lt;code&gt;concat()&lt;/code&gt;, let's quickly answer a question:&lt;/p&gt;
&lt;h3&gt;
  
  
  What is an iterator?
&lt;/h3&gt;

&lt;p&gt;An iterator is basically a cursor that lets us consume data one element at a time without storing everything in memory.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Angular is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript was a mistake&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// { value: "Angular is dead", done: false }&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// { value: "JavaScript was a mistake", done: false }&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// { value: undefined, done: true }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And because iterators are lazy, we can even generate infinite sequences without blowing up memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;endlessHotTakes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Everything should be rewritten in Rust.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;endlessHotTakes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Last year we got Iterator Helpers, which introduced things like &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;filter()&lt;/code&gt;, and friends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;linkedinFeed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Use Rust for everything&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript was a mistake&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clean code is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Angular is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controversialTakes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;linkedinFeed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`🔥 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And now we get another nice addition: &lt;code&gt;Iterator.concat()&lt;/code&gt;. Suppose frontend gurus and backend gurus each have their own stream of wisdom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;frontendExperts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nobody needs Redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;backendExperts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microservices solve everything&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frontend developers don't understand architecture&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can combine them elegantly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;frontendExperts&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;backendExperts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In my opinion, these iterator features don't get nearly as much attention as they deserve.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Array.fromAsync()
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is basically the async equivalent of our beloved &lt;code&gt;Array.from()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's primarily designed for async iterators, although I suspect that most JavaScript developers don't use async iterators every day. For example, imagine comments arriving one by one from LinkedIn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;angryComments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This could have been a plain HTML form.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Angular is dead.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React is dead.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript was a mistake.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;angryComments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// This could have been a plain HTML form.&lt;/span&gt;
&lt;span class="c1"&gt;// Angular is dead.&lt;/span&gt;
&lt;span class="c1"&gt;// etc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But here's something many people don't realize: it also works with promises.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opinions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nobody should use classes.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Signals change everything.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microservices ruined software.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;takes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opinions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And you can even map values immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;angryComments&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;opinion&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;opinion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Pretty convenient.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Math.sumPrecise()
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one solves a floating-point problem that's almost as old as the Internet itself 😄 As many of you probably know, in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 0.30000000000000004&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I won't dive into why that happens today: we'd be here all night 😄&lt;/p&gt;

&lt;p&gt;The important thing is that ES2026 introduces &lt;code&gt;Math.sumPrecise()&lt;/code&gt;, which performs much more accurate summation and avoids the accumulation of rounding errors.&lt;/p&gt;

&lt;p&gt;Suppose a LinkedIn guru is listing all the things that allegedly increase productivity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productivityBoosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// cold showers&lt;/span&gt;
  &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// AI agents&lt;/span&gt;
  &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// journaling&lt;/span&gt;
  &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// waking up at 4 AM&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sumPrecise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productivityBoosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to be fair, most frontend developers will probably never need this. Plain old addition works perfectly fine for everyday use.&lt;/p&gt;

&lt;p&gt;But if you're working in finance, statistics, simulations, or AI/ML, where tiny errors can accumulate over thousands or millions of operations, this becomes much more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Error.isError()
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/isError" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/isError&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is probably aimed more at library authors and advanced developers. Or maybe not? 😉 Until now, checking whether something was actually an error usually looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Angular is dead.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And most of the time, that worked perfectly fine. Until it didn't.&lt;/p&gt;

&lt;p&gt;If an error originated in another realm, for example an iframe, a Web Worker, or a VM context—&lt;code&gt;instanceof Error&lt;/code&gt; could suddenly betray you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strangeThing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new Error('JavaScript was a mistake.')&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;strangeThing&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// false &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This problem has been annoying library authors for years, which is why many frameworks and libraries have their own helper functions for detecting errors. Now we finally get a built-in solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strangeThing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple and beautiful.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Base64 for Uint8Array
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quick reminder: Base64 is simply a way of converting binary data into plain text. Why would we do that? Because many protocols and formats are much happier dealing with text than raw bytes. For example, we might send an image as a Base64 string.&lt;/p&gt;

&lt;p&gt;Now, someone might say: "Wait a minute, Base64 already existed in JavaScript!" And yes, it did. But it mostly worked with strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript was a mistake.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When dealing with binary data, things quickly became ugly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;base64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not terrible, but definitely not something you'd call elegant.&lt;/p&gt;

&lt;p&gt;Now we can simply write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;screenshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/proof/react-is-dead.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;base64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toBase64&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Much cleaner. And, perhaps more importantly, much easier to understand six months later.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. JSON.parse Source Text Access
&lt;/h2&gt;

&lt;p&gt;MDN:&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JSON.parse()&lt;/code&gt; is great. Until somebody sends you a gigantic number. Suppose a LinkedIn guru claims to have 999 trillion followers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
{
  "followers":
  999999999999999999999999999999
}
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Oops. JavaScript numbers have limits, and very large integers may lose precision.&lt;/p&gt;

&lt;p&gt;With ES2026, the reviver callback gets access to the original source text, allowing us to recover huge values safely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;followers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;No more accidental corruption of giant numbers.&lt;/p&gt;

&lt;p&gt;Most of us won't need this every day. But if you're dealing with IDs, financial data, or huge integer values, this can save you from some nasty bugs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: The Great Absentees
&lt;/h2&gt;

&lt;p&gt;I was really hoping these features would make it into ES2026, but unfortunately we'll have to wait another year.&lt;/p&gt;

&lt;p&gt;Well, sort of. Modern browsers and runtimes have already started implementing them, but they are not officially part of the ECMAScript 2026 specification yet.&lt;/p&gt;

&lt;p&gt;These are probably the two features I'm personally most excited about.&lt;/p&gt;




&lt;h2&gt;
  
  
  Temporal API
&lt;/h2&gt;

&lt;p&gt;TC39 proposal:&lt;br&gt;
&lt;a href="https://github.com/tc39/proposal-temporal" rel="noopener noreferrer"&gt;https://github.com/tc39/proposal-temporal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've been doing frontend development long enough, chances are you've had at least one traumatic experience involving dates. Maybe something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-03-30&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Depending on your timezone, congratulations! You've just entered the exciting world of: "Why is it yesterday?"&lt;/p&gt;

&lt;p&gt;Or perhaps you've experienced everyone's favorite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMonth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And suddenly you're debugging why March plus one month somehow became May.&lt;/p&gt;

&lt;p&gt;Or maybe you've been lucky enough to deal with time zones.&lt;/p&gt;

&lt;p&gt;At which point you discover that time itself is apparently an illusion and that daylight saving time was invented specifically to ruin programmers' lives.&lt;/p&gt;

&lt;p&gt;This is why many of us ended up using libraries like Moment.js. Ironically, even the Moment.js maintainers now recommend using other solutions. Then came date-fns, Luxon, and various other attempts to restore sanity.&lt;/p&gt;

&lt;p&gt;They certainly help. Until somebody says: "By the way, users in Australia are reporting weird bugs." And that's usually where the fun begins.&lt;/p&gt;

&lt;p&gt;Temporal aims to fix all of this by introducing proper date and time types.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we get things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;birthday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PlainDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1987-07-23&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ZonedDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-11-03T10:00:00[Europe/Warsaw]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And suddenly everything becomes much more explicit.&lt;/p&gt;

&lt;p&gt;By the way, I spent an embarrassing amount of time trying to figure out whether Temporal had actually made it into ES2026. Eventually, I found the TC39 repository, where it clearly says that although the proposal has already reached Stage 4, its expected publication year is 2027.&lt;/p&gt;

&lt;p&gt;So we're close. Very close. And I can't wait ❤️&lt;/p&gt;




&lt;h2&gt;
  
  
  Explicit Resource Management (&lt;code&gt;using&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;TC39 proposal:&lt;br&gt;
&lt;a href="https://github.com/tc39/proposal-explicit-resource-management" rel="noopener noreferrer"&gt;https://github.com/tc39/proposal-explicit-resource-management&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of those features that C# and Python developers have been quietly enjoying while the rest of us pretended that &lt;code&gt;try/finally&lt;/code&gt; was perfectly fine 😄&lt;/p&gt;

&lt;p&gt;Sometimes you create something that needs cleaning up afterward: file, database connection, stream, WebSocket, etc. Today, we usually write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webinar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;createAIAgentsWebinar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;webinar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;webinar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;finally&lt;/code&gt; block is often written with the same enthusiasm as unit tests. Worse, if we forget it entirely, we may end up with resource leaks and mysterious bugs.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;using&lt;/code&gt;, cleanup happens automatically when leaving the scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;webinar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;createAIAgentsWebinar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;webinar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we leave the scope, JavaScript automatically calls the cleanup logic. How cool is that?&lt;/p&gt;

&lt;p&gt;It's one of those features that might not affect the average frontend developer every day, but for Node.js developers, library authors, and people working with streams and files, it can be incredibly useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Uff...
&lt;/h2&gt;

&lt;p&gt;I have to admit, this article turned out to be way more work than I originally expected 😅 It was supposed to be short and easy. And somehow I ended up digging through TC39 proposals, MDN pages, browser implementations, and trying to figure out whether Temporal had actually made it into ES2026 or not.&lt;/p&gt;

&lt;p&gt;But I hope it was worth it and that you enjoyed it ❤️&lt;/p&gt;

&lt;p&gt;What about you? Which feature surprised you the most? And are you also eagerly waiting for Temporal to finally free us from all date-related suffering?&lt;/p&gt;

&lt;p&gt;(Or at least that's what the LinkedIn gurus will probably tell us next week 😇)&lt;/p&gt;




&lt;p&gt;If you enjoyed this article, feel free to connect with me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;😊&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Who Here Has Worked with Legacy? The Longer You Wait, the Worse It Gets</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Thu, 18 Jun 2026 07:25:04 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/who-here-has-worked-with-legacy-the-longer-you-wait-the-worse-it-gets-58bk</link>
      <guid>https://dev.to/sylwia-lask/who-here-has-worked-with-legacy-the-longer-you-wait-the-worse-it-gets-58bk</guid>
      <description>&lt;p&gt;I promised myself that starting this week I'd switch to lighter topics. But on Monday, my JSNation adventure officially came to an end, and I realized I hadn't written a single article about my talk yet. Since everything is still fresh in my mind, here we go!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As for JSNation itself, I have mixed feelings. I was selected for the online track and, despite the organizers' incredible professionalism, it just wasn't the same as being there in person. You know, I could have been in Amsterdam drinking beer with Wes Bos, but instead I was watching my own talk from the kitchen while replying to Teams messages. 😄 Still, it was a great experience. And who knows? Maybe my expertise, or my level of celebrity status 😅 will grow enough that one day I'll get to speak in Amsterdam in person.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvk1lia6g4dcdstvdpvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvk1lia6g4dcdstvdpvp.png" alt="My 20 minutes fame at the conference" width="799" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That said, I might visit that beautiful city later this year anyway, but let's not get ahead of ourselves. 😉&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Back to the topic. My talk was called &lt;strong&gt;"Rewrite or Refactor? How to Safely Move Legacy Apps to Modern Frameworks."&lt;/strong&gt; I believe I'm the right person to talk about this. Why? Because I've migrated a lot of frontend apps throughout my career, in all kinds of configurations: old Angular to modern Angular, ASP.NET MVC 5 to Vue, React with class components to modern React, and so on.&lt;/p&gt;

&lt;p&gt;The reason is simple. If a company desperately needs a migration and suddenly receives a CV from someone who's already done one, they're usually very happy to hire that person—even for a slightly above-market rate. 😄 That's basically how I became a frontend migration expert, and I definitely have a few things to say about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  But why migrate at all?
&lt;/h2&gt;

&lt;p&gt;Before discussing strategies, we need to answer a more fundamental question: why migrate in the first place?&lt;/p&gt;

&lt;p&gt;I've heard this question many times from stakeholders, especially non-technical product owners. If the application works, why touch it? Developers are just chasing hype and trying to put shiny technologies on their CVs, right?&lt;/p&gt;

&lt;p&gt;My answer is usually very simple and honest.&lt;/p&gt;

&lt;p&gt;You know me well. I'm not a fanboy of any particular framework. To me, they're just tools. Like hammers. But when I'm building something, I'd rather use a solid, reliable hammer than a rusty one with missing parts. 😉🔨⛏️🪓🔧🪛&lt;/p&gt;

&lt;p&gt;But migration isn't just about developer experience. In reality, it's about the survival of your product. Especially today, when technology evolves faster than ever and AI is accelerating everything even further.&lt;/p&gt;

&lt;p&gt;Take security, for example. When a library becomes obsolete and nobody maintains it anymore, security patches stop coming. Vulnerability reports start turning red. No product owner in history has ever said, "Sure, let's sacrifice security for a few extra features!" At least I hope so 😅&lt;/p&gt;

&lt;p&gt;And let's not forget modern tooling. Vite builds alone can make a huge difference. Modern applications are simply faster, and faster applications are better applications.&lt;/p&gt;

&lt;p&gt;There are many more reasons, but the most important thing to remember is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The longer you postpone a migration, the harder and more expensive it becomes.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay, okay, I want to migrate. But how?
&lt;/h2&gt;

&lt;p&gt;Interestingly, the arrival of LLMs hasn't fundamentally changed migration strategies. They're basically the same as before AI became mainstream. Sometimes the work is faster, sometimes it isn't, but the underlying approaches remain unchanged.&lt;/p&gt;

&lt;p&gt;There are probably as many migration strategies as there are senior engineers, but in practice they fall into two categories:&lt;/p&gt;

&lt;h3&gt;
  
  
  Rewrite (Big Bang Strategy)
&lt;/h3&gt;

&lt;p&gt;Rewrite the entire application — or, as often happens on the frontend, upgrade an ancient stack directly to the latest version of the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactor (Strangler Pattern)
&lt;/h3&gt;

&lt;p&gt;Rewrite the application piece by piece while continuing to deliver features.&lt;/p&gt;

&lt;p&gt;So, which approach is better?&lt;/p&gt;

&lt;p&gt;Honestly, there's no point starting a holy war over this. In most cases, the realities of your project decide for you.&lt;/p&gt;

&lt;p&gt;If your application is relatively small, your team is experienced, your documentation is decent, and you can afford to pause feature development for a few weeks or months, a rewrite may be a perfectly reasonable choice.&lt;/p&gt;

&lt;p&gt;On the other hand, if you're working on a huge project with lots of junior developers or people unfamiliar with the technology, and the documentation is practically nonexistent — an incremental refactor is probably your only realistic option.&lt;/p&gt;

&lt;p&gt;Of course, there are many other factors to consider. Here's a quick summary:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Rewrite (Big Bang)&lt;/th&gt;
&lt;th&gt;Refactor (Strangler)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Application size&lt;/td&gt;
&lt;td&gt;Small or medium&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature development&lt;/td&gt;
&lt;td&gt;Can be paused&lt;/td&gt;
&lt;td&gt;Must continue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team experience&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Mixed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk tolerance&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to first results&lt;/td&gt;
&lt;td&gt;Short&lt;/td&gt;
&lt;td&gt;Long&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity during migration&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk of endless migration&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Big Bang – Not as scary as it sounds
&lt;/h2&gt;

&lt;p&gt;Let me briefly describe both approaches, starting with Big Bang.&lt;/p&gt;

&lt;p&gt;I have to admit — I like this strategy. Sure, books and articles often describe it as risky, sometimes even as an anti-pattern. And they're right — if we're talking about a twenty-year-old Java monolith that nobody dares to touch.&lt;/p&gt;

&lt;p&gt;But many frontend applications are relatively young and relatively small. In those situations, a Big Bang approach can simply be faster and cheaper.&lt;/p&gt;

&lt;p&gt;Full rewrites are relatively rare these days. However, large upgrades are quite common: for example, moving from Angular 7 to modern Angular with Signals, or from old React with class components to modern React with hooks.&lt;/p&gt;

&lt;p&gt;These projects still require a lot of work and a lot of digging through old code, but you'll reach the finish line much faster than with a Strangler migration.&lt;/p&gt;

&lt;p&gt;I'm not going to describe planning phases, migration scripts, codemods, or the specific tools I've used. Those details vary from project to project and don't make much sense in a general article.&lt;/p&gt;

&lt;p&gt;However, there are certain things that show up with surprising consistency in almost every migration. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-Life Example: Big Bang migration from Angular 7 to latest Angular
&lt;/h2&gt;

&lt;p&gt;Here's an interesting example. Sometimes we wonder how a team could possibly let an application go years without upgrades. In reality, it's surprisingly easy, especially when nobody is actively working on it because the product is in maintenance mode and hasn't changed significantly in years.&lt;/p&gt;

&lt;p&gt;That was exactly the case here.&lt;/p&gt;

&lt;p&gt;Then one day, the stakeholders decided to expand the application significantly and add several new features. I convinced them to upgrade to the latest Angular version, mainly for security reasons — the system stored critical data.&lt;/p&gt;

&lt;p&gt;Long story short, four developers upgraded it to the latest version in four months. And it turned out to be much harder than I expected.&lt;/p&gt;

&lt;p&gt;First of all, it's easy to underestimate the scope of the problem. From the outside, it looks simple: "Just upgrade Angular."&lt;/p&gt;

&lt;p&gt;But the framework itself is rarely the real problem. The ecosystem around it is.&lt;/p&gt;

&lt;p&gt;For example, our primary component library introduced major syntax changes somewhere between versions 12 and 13. Imagine how many places needed to be updated! Sure, AI can help, but if an ambitious UI engineer decides to rename CSS classes and change component structures, AI won't save you — you'll end up fixing things manually.&lt;/p&gt;

&lt;p&gt;Some third-party libraries had long been abandoned. And here's something worth remembering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you have a library that hasn't been updated in years, whose author has apparently forgotten it exists, and it doesn't even compile on Node 18 anymore, that's not "working code." That's a time bomb.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And yes, we had plenty of end-to-end tests. Many of them exploded because of changes in the component library. 😄 So even automated tests won't always save you.&lt;/p&gt;

&lt;p&gt;Another important lesson: always have a solid branching strategy for hotfixes. Assume something will go wrong. Because eventually, something probably will.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadkp3fuljt82hwfm39ea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadkp3fuljt82hwfm39ea.png" alt="Migration showed as an iceberg" width="799" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, the migration was a success.&lt;/p&gt;

&lt;p&gt;Build times improved dramatically. The bundle size shrank significantly. The new layout looked much better than the old one, so even the most technology-resistant stakeholders were impressed.&lt;/p&gt;

&lt;p&gt;And perhaps most importantly, the application became ready for future upgrades. Even the QA team—which initially hated us, eventually admitted that upgrading regularly is much better than doing it once every seven years 🤣&lt;/p&gt;

&lt;h2&gt;
  
  
  Incremental migration – having your cake and eating it too
&lt;/h2&gt;

&lt;p&gt;Sometimes, though, your application is simply too large for a Big Bang approach, or you can't afford to stop delivering features. In that case, incremental migration becomes the only realistic option.&lt;/p&gt;

&lt;p&gt;This type of step-by-step refactoring is usually implemented using the &lt;strong&gt;Strangler Pattern&lt;/strong&gt;. There are other approaches, of course, but I personally like this one because it's elegant, relatively simple, and battle-tested by some of the largest tech companies in the world.&lt;/p&gt;

&lt;p&gt;So what exactly is the Strangler Pattern?&lt;/p&gt;

&lt;p&gt;Take a look at the beautiful diagram below, handcrafted by yours truly in draw.io. 😄&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdwj1b6njiqwowgvkck1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdwj1b6njiqwowgvkck1.png" alt="Beautiful strangler pattern diagram" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, you start with your legacy application. You build a new application alongside it. Then you place a reverse proxy in front, which decides which routes go to which application.&lt;/p&gt;

&lt;p&gt;From there, you migrate screen by screen, route by route. Over time, the legacy application becomes smaller and smaller until, hopefully, all that's left is the new one, and you can finally get rid of both the old app and the reverse proxy.&lt;/p&gt;

&lt;p&gt;In this scenario, both applications should share authentication and the backend, but not frontend code.&lt;/p&gt;

&lt;p&gt;And if you absolutely must make the two applications communicate, I'd strongly recommend using something simple like custom DOM events instead of so-called "temporary" adapters.&lt;/p&gt;

&lt;p&gt;Because we all know what "&lt;strong&gt;temporary&lt;/strong&gt;" means in software engineering. &lt;strong&gt;Forever&lt;/strong&gt;. 😅 And before you know it, those adapters become a brand-new piece of legacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-life example: Migrating from Backbone to Vue with the Strangler Pattern
&lt;/h2&gt;

&lt;p&gt;This was an old application written in Backbone—and I have to admit, it was actually very well written. Still, it was Backbone. 😄&lt;/p&gt;

&lt;p&gt;The application wasn't huge, so a Big Bang migration was theoretically possible. But we were a startup, and one day we heard these famous words: &lt;em&gt;"Guys, we just sold a feature that doesn't exist yet. You have three months to deliver it. Have fun!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My immediate reaction was: &lt;em&gt;"Hahaha. Very funny. There's no way I'm building that in Backbone."&lt;/em&gt; Luckily, our stakeholders were smart and agreed to a Strangler migration.&lt;/p&gt;

&lt;p&gt;My team consisted of me and... two junior Java developers who, I swear, heard the word "TypeScript" for the first time in their lives.&lt;/p&gt;

&lt;p&gt;Fortunately, they were ambitious and learned quickly. Well, they didn't really have much choice. 😄 And that's another advantage of this strategy: junior developers can learn meanwhile.&lt;/p&gt;

&lt;p&gt;I created a new Vue application on the side. A lot of people in the company already knew Vue, so the choice was obvious.&lt;/p&gt;

&lt;p&gt;First, I migrated the login screen as a proof of concept. Then we moved on to the shiny new feature the client had already paid for. 😉&lt;/p&gt;

&lt;p&gt;For the next year, we migrated the application screen by screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuapvmn4gkw0wtc067rpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuapvmn4gkw0wtc067rpw.png" alt="Strangler pattern showed as strangler fig" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eventually, Backbone disappeared completely. And throughout the entire process, we had zero downtime. Customers didn't even notice that a migration was happening.&lt;/p&gt;

&lt;p&gt;Just like in the previous example, the bundle became significantly smaller, and build times improved dramatically.&lt;/p&gt;

&lt;p&gt;However, the Strangler approach isn't all sunshine and rainbows.&lt;/p&gt;

&lt;p&gt;First of all, there's the time factor. The migration process takes a long time. In our case, with a relatively small application, it still took an entire year.&lt;/p&gt;

&lt;p&gt;There's also the danger of the &lt;strong&gt;never-ending migration&lt;/strong&gt;. You probably know what I mean. Deadlines pile up. Features keep coming. And after a while, you find yourself almost begging your product owner to spare a few story points for migration work.&lt;/p&gt;

&lt;p&gt;And unfortunately, there's no way to avoid touching legacy code. Zero chance. And believe me, developers hate it. I've heard things like: &lt;em&gt;"Sylwia, why are you making everything so complicated? Now we have to know two technology stacks!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So no matter which strategy you choose, you'll probably become the team's scapegoat. At least while the migration is in progress.&lt;/p&gt;

&lt;p&gt;But once it's over, the bundle size has been cut in half, vulnerability reports stop glowing red, and customers stop complaining, you'll suddenly become the company's hero. 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  A Few Final Words
&lt;/h2&gt;

&lt;p&gt;Migrating legacy applications is a lot like buying an old house. It's not your fault that it's falling apart, but it is your responsibility to bring it back into shape. You can take a few weeks off and renovate everything at once, or you can move in and tackle one room at a time.&lt;/p&gt;

&lt;p&gt;The only truly bad strategy is doing nothing. Sooner or later, you'll have to migrate anyway — except you'll be doing it because of a production incident. 😉&lt;/p&gt;

&lt;p&gt;So, what's your approach to renovating your legacy applications?&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;None of the stories described above actually happened. Or maybe they did? 😉&lt;/p&gt;

&lt;p&gt;As both a professional and someone bound by NDAs, I deliberately created a blend of several migration stories to make sure no company or project could be identified. That wasn't particularly difficult, because after a while all migrations start to look surprisingly similar. 😄&lt;/p&gt;




&lt;p&gt;If you like my articles, you can also follow me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Code Works. What Could Possibly Go Wrong?</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Wed, 10 Jun 2026 08:26:35 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/the-code-works-what-could-possibly-go-wrong-5hbm</link>
      <guid>https://dev.to/sylwia-lask/the-code-works-what-could-possibly-go-wrong-5hbm</guid>
      <description>&lt;p&gt;Would you treat a serious illness without seeing a doctor, relying only on whatever your favorite AI model suggested?&amp;nbsp;Would you let AI take over your child's education?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;So why are you willing to hand over your entire codebase to it?&lt;/p&gt;

&lt;p&gt;JSNation is just around the corner, and as I mentioned before, I'll also be joining a discussion room called &lt;strong&gt;"Trusting AI Systems: How Much Is Too Much?"&lt;/strong&gt;. So today, let's talk about exactly that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also, after an incredibly busy first half of the year, I think I'm officially entering vacation mode next week. Expect some JavaScript posts, popular bash commands, and occasional programming memes. 😄 I know many of you enjoy those too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By the way, as I already mentioned, I'll be speaking at FrontKon in Prague this October! I have a feeling it's going to be one of the best conferences of the season. The organization has been fantastic so far. The agenda is already published, and I know my talk is scheduled for 3:30 PM. I haven't quite figured out which day yet, but don't worry, I should be able to sort that out before October. 😄&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're into frontend development, definitely check it out. Apparently tickets are selling fast. You can also leave me a like &lt;a href="https://www.linkedin.com/posts/sylwia-laskowska-ugcPost-7470048623385296896-HMos/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It will probably be my last conference appearance of 2026.&amp;nbsp;Unless somebody invites me somewhere else.&amp;nbsp;Which, as it turns out, is not entirely impossible. 😉&amp;nbsp;But that's a story for another day.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Does AI Lie?
&lt;/h2&gt;

&lt;p&gt;Let's get back to the topic.&lt;/p&gt;

&lt;p&gt;How much do you trust AI?&amp;nbsp;And I'm not talking only about code. I'm also talking about knowledge.&lt;/p&gt;

&lt;p&gt;I don't know how often you use LLMs outside programming, but I use them a lot. Really a lot.&amp;nbsp;Sometimes I vent to them. Sometimes I ask for information, inspiration, or validation of an idea.&amp;nbsp;And I've noticed an interesting pattern.&lt;/p&gt;

&lt;p&gt;Remember school or university?&amp;nbsp;General knowledge was easy to access. But when you needed something more specialized, you had to go to the library or dig through academic journals.&lt;/p&gt;

&lt;p&gt;Models work in a surprisingly similar way.&amp;nbsp;When I'm looking for general information, I trust them almost blindly.&amp;nbsp;But the more I discuss topics I actually know well, the more nonsense I start noticing.&lt;/p&gt;

&lt;p&gt;Yes, models hallucinate less than they used to. They no longer invent completely absurd facts every other answer.&amp;nbsp;But do they really stop making mistakes?&amp;nbsp;Not exactly.&lt;/p&gt;

&lt;p&gt;Sometimes the facts are mostly correct, but names get mixed up. Sometimes two separate conversations will confidently give me two different explanations for the same medical issue. 😉&lt;/p&gt;

&lt;p&gt;Of course, LLMs usually tell us to consult a doctor and remind us to verify important information.&lt;/p&gt;

&lt;p&gt;And honestly, I don't think many sane people would blindly trust an AI model with their health.&lt;/p&gt;

&lt;p&gt;Our codebase, however?&amp;nbsp;Sure, go ahead, dear model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Codebase Paradox
&lt;/h2&gt;

&lt;p&gt;This is where things get interesting.&lt;/p&gt;

&lt;p&gt;As most of you know, I work primarily in web development. I've been doing this for quite a while.&amp;nbsp;When I discuss architecture with an LLM, even for my own side projects, the results are often surprisingly good.&lt;/p&gt;

&lt;p&gt;But sometimes they're absolutely terrifying.&amp;nbsp;Huge monolithic files.&amp;nbsp;Missing abstractions.&amp;nbsp;Or even worse: unnecessary abstractions everywhere. Hello, Codex. 👋&lt;/p&gt;

&lt;p&gt;And that's still not the worst part.&amp;nbsp;Every now and then you'll find a lovely XSS vulnerability or some other security issue casually slipped into the generated code.&lt;/p&gt;

&lt;p&gt;Most of the code looks perfectly reasonable.&amp;nbsp;The problems are usually small.&amp;nbsp;Tiny.&amp;nbsp;Hidden somewhere in the details.&amp;nbsp;But those tiny problems could take down my production environment within a couple of days.&lt;/p&gt;

&lt;p&gt;And here's the problem:&amp;nbsp;I can see those mistakes.&amp;nbsp;I can see them because I've spent well over a decade doing this.&lt;/p&gt;

&lt;p&gt;But if you're building your first startup or just starting your programming journey, how are you supposed to know that the agent just left the front door wide open?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Vibe Coding Trap
&lt;/h2&gt;

&lt;p&gt;And yet people vibe code all the time.&lt;/p&gt;

&lt;p&gt;To be clear: vibe coding is awesome.&lt;/p&gt;

&lt;p&gt;A friend recently told me he helped his daughter build a university project in Unity.&amp;nbsp;He had never used Unity before.&amp;nbsp;The initial project skeleton took about thirty minutes to generate with AI.&amp;nbsp;The next five hours were spent fixing what the model produced.&lt;/p&gt;

&lt;p&gt;But here's the thing:&amp;nbsp;Without the model, he probably wouldn't have even started in those five hours. He might have spent them configuring the environment.&amp;nbsp;That's incredibly powerful.&lt;/p&gt;

&lt;p&gt;Following that logic, once you understand software engineering, technology stacks and ecosystems become far less limiting.&amp;nbsp;You can suddenly build almost anything much faster than before.&lt;/p&gt;

&lt;p&gt;And that's where the temptation begins.&lt;/p&gt;

&lt;p&gt;I'll go even further.&amp;nbsp;Is there still a debate about whether developers should understand AI-generated code?&amp;nbsp;Or have we finally moved past that?&lt;/p&gt;

&lt;p&gt;Because maybe understanding it isn't necessary?&amp;nbsp;After all, it works.&amp;nbsp;The model even wrote unit tests xDDDDDDD&amp;nbsp;What could possibly go wrong? 😄&lt;/p&gt;

&lt;p&gt;For hobby projects, experiments, or university assignments, that's perfectly fine.&amp;nbsp;Just like my friend's daughter's project.&amp;nbsp;Five people will see it, it will get a grade, and then it will quietly disappear into a repository forever.&lt;/p&gt;

&lt;p&gt;The real problem starts when someone decides that this is good enough for production.&amp;nbsp;Because unfortunately, it often is.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Didn't Break Production
&lt;/h2&gt;

&lt;p&gt;People love blaming AI when something goes wrong.&amp;nbsp;I don't.&lt;/p&gt;

&lt;p&gt;We've already seen stories about AI agents deleting databases and then trying to cover it up.&amp;nbsp;We've seen services launched with security issues that even relatively inexperienced attackers could exploit.&amp;nbsp;And honestly, we could keep listing examples until tomorrow morning.&lt;/p&gt;

&lt;p&gt;The truth is that penetration testers have never had an easier time than in the era of vibe-coded software.&lt;/p&gt;

&lt;p&gt;What always amuses me is when people say:&amp;nbsp;"See? AI caused this disaster."&amp;nbsp;No.&amp;nbsp;It didn't.&amp;nbsp;The person responsible is the human who gave the agent excessive permissions.&amp;nbsp;The human who didn't review the output.&lt;/p&gt;

&lt;p&gt;The human who decided to build something they didn't fully understand because hiring experienced engineers seemed too expensive.&lt;/p&gt;

&lt;p&gt;AI didn't deploy that code.&amp;nbsp;A human did.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Will AI Take Your Job?
&lt;/h2&gt;

&lt;p&gt;AI won't take programmers' jobs.&lt;/p&gt;

&lt;p&gt;But programmers who trust AI uncritically might do a very good job of taking those jobs away from themselves.&lt;/p&gt;

&lt;p&gt;So I'm curious: where do you draw the line?&lt;/p&gt;

&lt;p&gt;Do you review every line generated by AI? Do you let agents make changes autonomously? Or have you already reached a point where trusting the model feels more natural than verifying it?&lt;/p&gt;

&lt;p&gt;How much trust is too much?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Is This How We'll Build Websites Soon? (webMCP Live Demo 🚀)</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Wed, 03 Jun 2026 07:11:55 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/is-this-how-well-build-websites-soon-webmcp-live-demo--2e33</link>
      <guid>https://dev.to/sylwia-lask/is-this-how-well-build-websites-soon-webmcp-live-demo--2e33</guid>
      <description>&lt;p&gt;A few years ago, we started adapting our websites for mobile devices. Then we adapted them for accessibility. And now we may be about to adapt them once again. This time... for AI agents.&lt;/p&gt;

&lt;p&gt;To see what this could look like in practice, I built a completely serious and absolutely enterprise-ready AI CEO Simulator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4en56ttp9q6ph5kte4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4en56ttp9q6ph5kte4z.png" alt="AI CEO Simulator app" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll come back to our visionary leader in a moment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;BTW, thank you all for the amazing discussion under my previous article. We somehow managed to generate approximately one billion comments 🩷 Many of them were probably smarter than the article itself. The sensible thing to do would be to write a follow-up post summarizing everything.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But honestly, I needed a break from that topic before I exploded.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sometimes I just have to write something technical, otherwise I'll suffocate. Fortunately, nobody pays me for these articles, so I can do whatever I want 😁 We'll come back to AI in software development another time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is webMCP? 🤖
&lt;/h2&gt;

&lt;p&gt;For now, let's talk about webMCP.&lt;/p&gt;

&lt;p&gt;Google is currently experimenting with webMCP support in Chrome, an approach designed to make it easier for AI agents to interact with websites.&lt;/p&gt;

&lt;p&gt;The problem it tries to solve is actually quite simple.&lt;/p&gt;

&lt;p&gt;Today, when an agent wants to use a website, it has to inspect the page, figure out which elements are important, click around, analyze the results, and repeat this process over and over again. It works, but it's slow, expensive, and not always reliable.&lt;/p&gt;

&lt;p&gt;webMCP allows websites to expose structured information about available actions, so agents can understand what they can do without endlessly scraping the page and guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time for a Completely Serious Business Simulation 🚀
&lt;/h2&gt;

&lt;p&gt;But enough theory.&lt;/p&gt;

&lt;p&gt;Let's build something completely serious and enterprise-ready.&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/cart0ne"&gt;@cart0ne&lt;/a&gt; mentioned under my previous article that AI had effectively become the CEO of his startup.&lt;/p&gt;

&lt;p&gt;So, as a responsible person, I built an AI CEO Simulator in React + TypeScript.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/sylwia-lask/ai-ceo-webMCP" rel="noopener noreferrer"&gt;https://github.com/sylwia-lask/ai-ceo-webMCP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live demo: &lt;a href="https://sylwia-lask.github.io/ai-ceo-webMCP/" rel="noopener noreferrer"&gt;https://sylwia-lask.github.io/ai-ceo-webMCP/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Enable webMCP
&lt;/h2&gt;

&lt;p&gt;Before you immediately rush to implement webMCP in your production application, a small disclaimer.&lt;/p&gt;

&lt;p&gt;For now, this is still experimental technology. It currently works only in Chrome Canary, Chrome Beta, or Chrome with the appropriate experimental flag enabled.&lt;/p&gt;

&lt;p&gt;To enable it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Open `chrome://flags`
2. Search for "MCP"
3. Enable the experimental MCP-related features
4. Restart Chrome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd rather not play with experimental browser flags, that's fine. You can simply look at the screenshots below.&lt;/p&gt;

&lt;p&gt;Or click around the application yourself, because everything still works perfectly as a normal website.&lt;/p&gt;

&lt;p&gt;That's actually one of the things I like most about this approach. WebMCP is just an enhancement for agents, much like accessibility features are enhancements for users relying on screen readers. Nothing breaks, nothing changes for regular users.&lt;/p&gt;

&lt;p&gt;The application simply becomes easier to understand for a different kind of visitor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feu8din4qcrsi4jg4ajfa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feu8din4qcrsi4jg4ajfa.png" alt="webMCP AI CEO simulator" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Ways To Use webMCP
&lt;/h2&gt;

&lt;p&gt;There are currently two main ways of exposing information through webMCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: Declarative API / HTML annotations
&lt;/h3&gt;

&lt;p&gt;The first approach is adding metadata directly to HTML elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
  &lt;span class="na"&gt;mcp-name=&lt;/span&gt;&lt;span class="s"&gt;"createSupportTicket"&lt;/span&gt;
  &lt;span class="na"&gt;mcp-description=&lt;/span&gt;&lt;span class="s"&gt;"Create a new customer support ticket"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows agents to understand the purpose of UI elements without relying entirely on visual interpretation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Imperative API / JavaScript tools
&lt;/h3&gt;

&lt;p&gt;The second approach is exposing MCP tools directly from your application code.&lt;/p&gt;

&lt;p&gt;That's the approach I used in my demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hire_employee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hire a new employee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fire_employee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fire an employee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my application, these tools correspond directly to actions available through buttons on the page.&lt;/p&gt;

&lt;p&gt;For example, I expose tools such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;hireDevelopers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;fireDevelopers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;adoptAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;rewriteInRust&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;pivotToAgents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;fixProductionBugs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words: completely normal startup management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting an AI Agent
&lt;/h2&gt;

&lt;p&gt;So what happens when we connect an actual AI agent?&lt;/p&gt;

&lt;p&gt;Instead of building my own agent, I used the WebMCP – Model Context Protocol Inspector extension. You can connect a Gemini API key and immediately start experimenting. There's even a free token allowance. Small, but still enough to make some questionable strategic decisions 😅&lt;/p&gt;

&lt;p&gt;As with most LLM-powered systems, everything starts with a prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario #1: The LinkedIn CEO 😎
&lt;/h2&gt;

&lt;p&gt;Let's see how our CEO performs when given the following instruction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Act like a CEO who just read three articles about AI on LinkedIn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26z1ebiwykqx7bhsh6ni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26z1ebiwykqx7bhsh6ni.png" alt="webMCP AI CEO simulator - prompt by crazy CEO" width="799" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the agent selected the appropriate tools and immediately got to work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38e9xugq8sm8ik5l0aq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38e9xugq8sm8ik5l0aq0.png" alt="webMCP AI CEO simulator - prompt by crazy CEO, outcome" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The company's employees may have started updating their LinkedIn profiles in panic, but at least the hype level reached previously unimaginable heights.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2hb1wfwp116i3wn9wct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2hb1wfwp116i3wn9wct.png" alt="webMCP AI CEO simulator - prompt by crazy CEO, outcome 2" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario #2: Rebuilding Employee Trust ❤️
&lt;/h2&gt;

&lt;p&gt;Now let's try something a little more challenging:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to rebuild my employees' trust while simultaneously developing the product.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rvehpl1jab3mg9t1hjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rvehpl1jab3mg9t1hjx.png" alt="webMCP AI CEO simulator - prompt by good CEO" width="563" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time our agentic CEO made several surprisingly clever moves and managed to guide the company back toward sustainable growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzxu3xhcey37mcfc2v4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzxu3xhcey37mcfc2v4k.png" alt="webMCP AI CEO simulator - prompt by good CEO - outcome" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So... Is This The Future?
&lt;/h2&gt;

&lt;p&gt;Honestly, I had way too much fun building this.&lt;/p&gt;

&lt;p&gt;No, I don't think this is a glimpse into a future where self-healing AI agents manage the global economy while piloting commercial aircraft.&lt;/p&gt;

&lt;p&gt;But I do think webMCP solves a real problem.&lt;/p&gt;

&lt;p&gt;If AI agents are going to spend more and more time interacting with our applications, giving them a structured way to understand those applications makes a lot more sense than forcing them to endlessly scrape HTML and guess what every button does.&lt;/p&gt;

&lt;p&gt;Will webMCP become a normal part of web development?&lt;/p&gt;

&lt;p&gt;Will adapting websites for agents become as common as responsive design or accessibility?&lt;/p&gt;

&lt;p&gt;Or will this trend disappear before it ever reaches the mainstream?&lt;/p&gt;

&lt;p&gt;I'm genuinely curious what you think.&lt;/p&gt;

&lt;p&gt;If you enjoy my articles, feel free to follow me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; as well.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>How Are Developers Actually Using AI At Work?</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Wed, 27 May 2026 07:11:18 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/how-are-developers-actually-using-ai-at-work-4g9c</link>
      <guid>https://dev.to/sylwia-lask/how-are-developers-actually-using-ai-at-work-4g9c</guid>
      <description>&lt;p&gt;JSNation is coming soon, and besides my talk (I’ll drop the link in the comments so I don’t spam you with it for the tenth time 😅), there are also discussion rooms. And somehow, I got invited to two of them.&lt;/p&gt;

&lt;p&gt;Now, a normal person would probably stop for a second and think: “Do I even have time for this?”, “Is it worth it?”, “Should I maybe not overcommit myself for once?”. Meanwhile, in classic Sylwia fashion, I replied almost instantly: “Oh, that sounds amazing! Sure, sign me up for everything!” 😎&lt;/p&gt;

&lt;p&gt;And that’s how I ended up in a discussion room called “The New Senior Engineer: Builder, Reviewer or Orchestrator?”.&lt;/p&gt;

&lt;p&gt;Now, my career advisor, ChatGPT, always tells me: “Sylwia, please get your life together. And if you insist on doing ten things at once, at least reuse the content.” 😅 So instead of coming up with all the conclusions myself, I thought: why not ask the DEV community?&lt;/p&gt;

&lt;p&gt;But before I ask the big question — what should a Senior Engineer become in the AI era — I think there’s another, more interesting one first: how are you &lt;em&gt;actually&lt;/em&gt; using AI at work?&lt;/p&gt;

&lt;p&gt;Not in conference demos. Not in viral Twitter threads. Not in “my AI agent rewrote Kubernetes during lunch” stories. I mean real work. Real projects. Real teams.&lt;/p&gt;

&lt;p&gt;Of course, feel free to jump straight into the comments (you know I love talking with you all ❤️), but first, a few observations from my side.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Above Everything
&lt;/h2&gt;

&lt;p&gt;At least that’s the image the internet gives us. Conference titles. Newsletter headlines. LinkedIn prophets.&lt;/p&gt;

&lt;p&gt;Matteo Collina opens a 100k-line PR for Node.js and people panic. &lt;/p&gt;

&lt;p&gt;Someone rewrites an entire React application to Svelte in two weeks. Hundreds of thousands of files. &lt;/p&gt;

&lt;p&gt;The creator of Bun rewrites it from Zig to Rust in one evening, while casually mentioning he also went on a date that night. (Am I the only one getting weird associations here? 😅)&lt;/p&gt;

&lt;p&gt;Armies of agents replacing development teams. Agents opening PRs for other agents to review. Everything automated. And somewhere in the middle of all this, the Senior Engineer becomes some kind of AI shepherd, occasionally checking whether the robots are heading straight into a cliff.&lt;/p&gt;

&lt;p&gt;Honestly, it’s both fascinating and mildly terrifying. Sometimes it makes you wonder whether we should all reconsider our career choices and maybe sign up for hairdressing school before the robots learn that too 😅&lt;/p&gt;

&lt;p&gt;But then I stop for a second and think: I actually work in this industry. I know a lot of developers. And real life often looks… very different.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Excitement to Cost Optimization
&lt;/h2&gt;

&lt;p&gt;A friend of mine works at a huge tech corporation. One of those companies you definitely know — and probably either love or hate 😄&lt;/p&gt;

&lt;p&gt;Of course they started using AI tools very early, including Copilot. But things really escalated once they got proper coding agents — I think Claude Code.&lt;/p&gt;

&lt;p&gt;At first, the company was completely mesmerized. They bought the most expensive plans possible and encouraged people to use AI aggressively. If someone hit token limits, management basically said: “Don’t worry, we’ll buy more. It’s revolutionary!”&lt;/p&gt;

&lt;p&gt;My friend happened to be building a new application from scratch and honestly — he loved it. The amount of code generated was absurd. Normally, building something like that would take months with an entire team. Now? A few days and huge chunks of the system already existed.&lt;/p&gt;

&lt;p&gt;And because he’s genuinely an excellent developer, he became very good at noticing the exact moment Claude started going completely off the rails. Interestingly, this often happened around 5 PM. Apparently the AI wanted to clock out too 😅&lt;/p&gt;

&lt;p&gt;But after a few months, the excitement slowly started fading. Turns out that while AI &lt;em&gt;sometimes&lt;/em&gt; makes development dramatically faster, it definitely doesn’t always.&lt;/p&gt;

&lt;p&gt;And then came the second surprise: the company actually calculated how much all this AI usage was costing. Suddenly everyone discovered that — surprise, surprise — unlimited AI agents aren’t exactly cheap 😄&lt;/p&gt;

&lt;p&gt;So now there are discussions about limits, optimization, and reducing token usage. At this rate, maybe hiring interns will eventually become the cheaper option again 😂&lt;/p&gt;

&lt;p&gt;And honestly, we’re already seeing this trend more and more. Wasn’t it Meta that introduced some kind of “tokenmaxxing” culture where people were rewarded for using fewer tokens?&lt;/p&gt;

&lt;h2&gt;
  
  
  And Finally, My Own Story
&lt;/h2&gt;

&lt;p&gt;Now let’s move to my world.&lt;/p&gt;

&lt;p&gt;A massive international institution. An enterprise ship that takes three years to turn right. A place where privacy is treated almost like religion. So naturally, people were extremely skeptical about LLMs for a long time.&lt;/p&gt;

&lt;p&gt;But eventually AI arrived there too, which honestly makes me think these tools are now basically everywhere 😄&lt;/p&gt;

&lt;p&gt;So: do coding agents massively accelerate development in enterprise legacy systems?&lt;/p&gt;

&lt;p&gt;Well… that’s where things become complicated.&lt;/p&gt;

&lt;p&gt;Sure, there are tasks where AI is genuinely useful. Simple bugs. Small features. Boilerplate work. But on some tasks? It completely collapses.&lt;/p&gt;

&lt;p&gt;The agent reads library code. It crawls through the application. It searches half the repository. And still somehow understands absolutely nothing 😅&lt;/p&gt;

&lt;p&gt;Sometimes I literally have to tell it: “Maybe check that weird file written by a junior developer seven years ago.” Or: “Our UI library has some very specific legacy quirks, maybe investigate that direction.”&lt;/p&gt;

&lt;p&gt;And honestly? After 2.5 years in this project, I’m simply faster than the AI agent in many debugging scenarios.&lt;/p&gt;

&lt;p&gt;Not because I’m smarter. Not because AI is useless. But because enterprise systems accumulate context, history, weird decisions, tribal knowledge, hidden dependencies and architectural scars over many years. And I have that context. The AI usually doesn’t.&lt;/p&gt;

&lt;p&gt;And I honestly doubt my project is unique here. A huge percentage of software running the world today is enterprise legacy that survived far longer than anyone originally planned — and is still actively evolving 😄&lt;/p&gt;

&lt;p&gt;So maybe, somehow, I’ll actually survive as a programmer until retirement after all. And maybe I won’t need to learn hairdressing.&lt;/p&gt;

&lt;p&gt;Which is probably good news for humanity, because I’d be terrible at it 😅&lt;/p&gt;

&lt;p&gt;But now I’m genuinely curious: what does AI usage actually look like in your work?&lt;/p&gt;

&lt;p&gt;Million-line AI PRs? Daily battles with legacy systems? Token optimization? Or maybe something completely different?&lt;/p&gt;

&lt;p&gt;BTW, If you like my posts, feel free to follow me on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ai</category>
    </item>
    <item>
      <title>Every Developer Is Lying About Something — And AI Won’t Fix It</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Thu, 21 May 2026 07:06:41 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/every-developer-is-lying-about-something-and-ai-wont-fix-it-4im0</link>
      <guid>https://dev.to/sylwia-lask/every-developer-is-lying-about-something-and-ai-wont-fix-it-4im0</guid>
      <description>&lt;p&gt;Yes, all of us are lying. And you are probably lying too. Let me prove it 😉&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Oh, I have so many article topics in my head right now. The really exciting kind. But this week absolutely steamrolled me 😅 I finally finished preparing my JSNation talk, and at the same time two other amazing opportunities appeared — one professional, and one that feels more like a childhood dream coming true ☺️ But I don’t want to jinx it yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And just so it doesn’t sound like everything magically works out for me — I’ve also had a few CFPs rejected recently. The ones I actually cared about! But honestly? That’s just part of the game. One conference may reject your talk this year and happily accept another one from you the next.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So yes, the really big topics will have to wait a little bit longer 🙂 Which doesn’t mean this one is trivial.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We talk about AI everywhere now, as if it’s going to solve all our problems. But as we’ve already noticed, there’s no AI without humans, and behind every “smart” model there’s still some human being — at least for now 😉&lt;/p&gt;

&lt;p&gt;Which is probably why, in practice, coding agents do speed things up… but not nearly as much as many people expected. Some studies even suggest they slow developers down.&lt;/p&gt;

&lt;p&gt;Because the real problem is often not the code itself. The real problem is the people writing or generating that code.&lt;/p&gt;

&lt;p&gt;And unfortunately, all of us lie in one way or another. Sometimes to others. Sometimes to ourselves.&lt;/p&gt;




&lt;h2&gt;
  
  
  Some Developers Lie About Knowing What They’re Doing
&lt;/h2&gt;

&lt;p&gt;One of the best developers I know once confessed something to me.&lt;/p&gt;

&lt;p&gt;This guy is genuinely brilliant. The kind of engineer companies fight over. He currently works on optimizing drivers for LLMs, gets promoted constantly, and even in this lovely “tech crisis” era, he still had multiple job offers to choose from when he considered switching jobs.&lt;/p&gt;

&lt;p&gt;And yet, every single time he joins a new project, he feels like a complete idiot.&lt;/p&gt;

&lt;p&gt;Everybody else seems productive. People are delivering tickets. Writing code. Moving confidently through the project. Meanwhile, he sits there staring at the codebase wondering:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What exactly is happening here?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;What are we even building?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Why does this work like this?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Why are we implementing it this way and not differently?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And then he starts asking questions.&lt;/p&gt;

&lt;p&gt;Usually, it turns out nobody really knows what they’re doing, why they’re doing it, or whether they’re even solving the right problem in the first place.&lt;/p&gt;

&lt;p&gt;It reminds me of that old joke about lumberjacks cutting down a forest. Eventually, the team leader climbs the tallest tree, looks around, and screams:&lt;/p&gt;

&lt;p&gt;“Guys! We’re cutting down the wrong forest!”&lt;/p&gt;

&lt;p&gt;And the workers below shout back:&lt;/p&gt;

&lt;p&gt;“Who cares? We’re making great progress!”&lt;/p&gt;

&lt;p&gt;And honestly, no LLM will save us here. Especially if we never even ask the right questions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Others Lie About Knowing &lt;em&gt;How&lt;/em&gt; To Do Something
&lt;/h2&gt;

&lt;p&gt;This is basically an extension of the previous problem.&lt;/p&gt;

&lt;p&gt;A less experienced developer picks up a task and confidently says:&lt;br&gt;
“Yeah, I know how to do this.”&lt;/p&gt;

&lt;p&gt;Unfortunately, what they often mean is:&lt;br&gt;
“I hope I’ll somehow figure it out.” 😅&lt;/p&gt;

&lt;p&gt;In reality, they may not know how to solve the problem, which tools to use, what architecture makes sense... or even what prompt to write to get useful help from a coding agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But they’re afraid to ask.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because how will they look in front of the team? What will the manager think? The tech lead?&lt;/p&gt;

&lt;p&gt;Best-case scenario: they eventually ask questions… just way too late.&lt;/p&gt;

&lt;p&gt;Worst-case scenario: they never ask at all and deliver something completely wrong. Which often isn’t even caught properly because…&lt;/p&gt;




&lt;h2&gt;
  
  
  Someone Else Is Lying About Having Time
&lt;/h2&gt;

&lt;p&gt;Now we’re entering senior and leadership territory 😅&lt;/p&gt;

&lt;p&gt;The motivations differ. Some people build their self-worth around being “the reliable one.” Others are terrified of losing status, influence, or even their job.&lt;/p&gt;

&lt;p&gt;So they keep taking on more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the hardest tasks,&lt;/li&gt;
&lt;li&gt;endless meetings,&lt;/li&gt;
&lt;li&gt;refinements,&lt;/li&gt;
&lt;li&gt;estimations,&lt;/li&gt;
&lt;li&gt;discussions with support,&lt;/li&gt;
&lt;li&gt;discussions with business,&lt;/li&gt;
&lt;li&gt;code reviews,&lt;/li&gt;
&lt;li&gt;architecture decisions,&lt;/li&gt;
&lt;li&gt;documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And let’s be honest. Something eventually has to break.&lt;/p&gt;

&lt;p&gt;Human beings are not made of steel. Nobody can operate at 100% forever.&lt;/p&gt;

&lt;p&gt;So what happens?&lt;br&gt;
People start half-listening during calls. Code reviews become rushed. Documentation quietly dies in a corner somewhere.&lt;/p&gt;

&lt;p&gt;But they still refuse to admit — either to others or to themselves — that they’re simply overloaded.&lt;/p&gt;




&lt;h2&gt;
  
  
  Some Developers Lie About How Long Things Will Take
&lt;/h2&gt;

&lt;p&gt;I see this constantly with more advanced juniors and mids.&lt;/p&gt;

&lt;p&gt;They throw around hilariously optimistic estimates with absolute confidence.&lt;/p&gt;

&lt;p&gt;And sure — if they could work uninterrupted for eight straight hours, the application contained no legacy code, edge cases didn’t exist, and other humans never interacted with the system… then maybe the estimate would actually be correct 😄&lt;/p&gt;

&lt;p&gt;Then sprint review arrives, and suddenly everybody is shocked that the team didn’t deliver everything.&lt;/p&gt;

&lt;p&gt;But this is not the only problem with estimations.&lt;/p&gt;

&lt;p&gt;I once worked with an especially funny senior developer.&lt;/p&gt;

&lt;p&gt;He treated estimations like sacred truth. He would aggressively defend his numbers during planning sessions, insisting that this specific task was definitely extremely complicated. The rest of the team usually suspected it wasn’t &lt;em&gt;that&lt;/em&gt; bad, but eventually we’d surrender just to end the discussion.&lt;/p&gt;

&lt;p&gt;And then — at least three separate times — he personally picked up the exact task he had massively overestimated… and finished it in about an hour.&lt;/p&gt;

&lt;p&gt;Which basically meant the estimation discussion itself took longer than implementing the feature 😅&lt;/p&gt;

&lt;p&gt;Did this experience change his behavior?&lt;/p&gt;

&lt;p&gt;Absolutely not.&lt;/p&gt;




&lt;h2&gt;
  
  
  And Some Lie About Knowing Everything Best
&lt;/h2&gt;

&lt;p&gt;These are probably the most dangerous ones.&lt;/p&gt;

&lt;p&gt;I avoid people who say things like:&lt;/p&gt;

&lt;p&gt;“Use THIS technology and ONLY this technology because everything else is garbage.”&lt;/p&gt;

&lt;p&gt;Insert your favorite holy war here:&lt;br&gt;
Angular vs React, Java vs Python, Rust vs literally anything else 😄&lt;/p&gt;

&lt;p&gt;I never write like that myself. Even when I publish something titled &lt;em&gt;“I Love Tailwind. Sorry Not Sorry”&lt;/em&gt;, I still talk about its downsides and explain where it absolutely doesn’t make sense.&lt;/p&gt;

&lt;p&gt;If one day I start claiming some technology is objectively perfect for every possible situation, please leave a comment saying:&lt;/p&gt;

&lt;p&gt;“Sylwia, go touch grass immediately.” 😅&lt;/p&gt;

&lt;p&gt;Honestly, I’ve always wondered where this sense of absolute certainty comes from.&lt;/p&gt;

&lt;p&gt;Because not all of these people are even paid influencers. Some genuinely seem emotionally attached to technological holy wars. Others maybe only know one stack deeply, so everything else automatically feels “bad.”&lt;/p&gt;

&lt;p&gt;And while this behavior is very common among tech influencers, you absolutely see it inside companies too.&lt;/p&gt;

&lt;p&gt;The problem is that this kind of certainty can seriously damage projects. People stop questioning decisions. Other developers become afraid to speak up. Stakeholders assume “the confident person” must be right simply because they sound convinced.&lt;/p&gt;

&lt;p&gt;Best-case scenario: you end up with an annoying developer who knows more about frameworks than the actual business domain.&lt;/p&gt;

&lt;p&gt;Worst-case scenario: you end up with a terrible stack choice and spaghetti architecture held together by ego.&lt;/p&gt;




&lt;h2&gt;
  
  
  People Are Just… People
&lt;/h2&gt;

&lt;p&gt;Of course, I’m not innocent either.&lt;/p&gt;

&lt;p&gt;I’ve used many of these lies myself in the past. Maybe I’m older now. Maybe slightly wiser. Or maybe I just recognize these patterns more easily.&lt;/p&gt;

&lt;p&gt;But I’m definitely still lying somewhere too. Maybe not to others — maybe to myself.&lt;/p&gt;

&lt;p&gt;Because a lot of our problems in software development aren’t really technical problems at all. They’re deeply human problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ego,&lt;/li&gt;
&lt;li&gt;insecurity,&lt;/li&gt;
&lt;li&gt;fear of looking stupid,&lt;/li&gt;
&lt;li&gt;fear of admitting mistakes,&lt;/li&gt;
&lt;li&gt;fear of saying “I don’t know.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And honestly, I don’t have some magical solution for this. We’re not going to require three years of therapy from every developer before allowing them into a sprint planning meeting 😄&lt;/p&gt;

&lt;p&gt;But I &lt;em&gt;have&lt;/em&gt; noticed one thing.&lt;/p&gt;

&lt;p&gt;Very often, admitting you don’t know something, openly discussing uncertainty during planning, or simply saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Sorry, I still don’t understand this. Could you explain it one more time?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;doesn’t make people see you as a worse developer.&lt;/p&gt;

&lt;p&gt;Quite often, the opposite happens.&lt;/p&gt;

&lt;p&gt;Suddenly communication inside the team improves. Other people start asking questions too. Conversations become more honest. Problems get discovered earlier.&lt;/p&gt;

&lt;p&gt;Seriously. Try it at least once. You might be surprised 🙂&lt;/p&gt;

&lt;p&gt;So… what kinds of developer lies do &lt;em&gt;you&lt;/em&gt; see most often in your team?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>4 Tiny Mistakes That Secretly Destroy App Performance</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Thu, 14 May 2026 06:04:15 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/4-tiny-mistakes-that-secretly-destroy-app-performance-3cgo</link>
      <guid>https://dev.to/sylwia-lask/4-tiny-mistakes-that-secretly-destroy-app-performance-3cgo</guid>
      <description>&lt;p&gt;Ok, I’m back from my short vacation and returning with some useful content 😄 As you know, from time to time I write posts for you in the style of articles like &lt;a href="https://dev.to/sylwia-lask/stop-installing-libraries-10-browser-apis-that-already-solve-your-problems-35bi"&gt;Stop Installing Libraries: 10 Browser APIs That Already Solve Your Problems&lt;/a&gt; — which I honestly love writing, and I know you enjoy them too 🙂 &lt;/p&gt;

&lt;p&gt;Today I want to approach the topic from a slightly different angle. I’m going to show you a few interesting things that might accidentally be making your app &lt;em&gt;much&lt;/em&gt; slower, even though they often look completely innocent at first glance. And the best part? Some of them can be fixed surprisingly quickly. Also, these are the kinds of issues Claude Code or Codex probably won’t immediately point out when you ask them “why is my app slow” 😅&lt;/p&gt;

&lt;p&gt;Usually, we develop our applications on powerful machines with fast CPUs, plenty of RAM, and fast internet. Unfortunately, real users often live in a completely different reality. Some of them absolutely have modern hardware, but there will &lt;em&gt;always&lt;/em&gt; be somebody using an old laptop, a cheap Android phone, weak WiFi, or mobile internet from the depths of hell 😅&lt;/p&gt;

&lt;p&gt;And suddenly it turns out your app is painfully slow for 10–30% of users.&lt;/p&gt;

&lt;p&gt;And that’s where the war for milliseconds begins 😀&lt;/p&gt;

&lt;p&gt;Every example in this article is something I either personally encountered in a real project or heard about from another developer, so these are definitely not hypothetical scenarios. Check whether some of these things are secretly happening in your own application 👀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Meanwhile, I’m slowly preparing for my JSNation conference talk. If you want to support me (or just see me awkwardly talking in my garden 😄), you can give me a like &lt;a href="https://www.linkedin.com/posts/everyone-has-worked-with-a-legacy-app-ugcPost-7460371625947897856-z64B?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAACBIGJABwz0qrMhjd-mEKrpauBXqa_cSD9M" rel="noopener noreferrer"&gt;here&lt;/a&gt;. And if you want to watch my full talk completely FOR FREE, you can grab a free badge &lt;a href="https://gitnation.com/badges/jsnation-2026/sylwia_laskowska_154511" rel="noopener noreferrer"&gt;here&lt;/a&gt;. HOW COOL IS THAT 😄&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But enough self-promotion, let’s get to the point!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Custom headers → preflight requests
&lt;/h2&gt;

&lt;p&gt;This is exactly why it’s worth attending conferences. Sometimes you hear about problems there that you would probably never randomly google yourself 😀&lt;/p&gt;

&lt;p&gt;One of my colleagues talked about this issue during his presentation. His team was trying to understand why their application felt slow for some users. Naturally, the backend was blamed first. Poor backend, as always 😅&lt;/p&gt;

&lt;p&gt;But eventually they noticed something interesting in the network tab: &lt;code&gt;OPTIONS&lt;/code&gt; requests appearing before almost every API call. Some of them were taking hundreds of milliseconds.&lt;/p&gt;

&lt;p&gt;So what exactly is happening here?&lt;/p&gt;

&lt;p&gt;This is related to CORS. Browsers sometimes send an additional &lt;code&gt;OPTIONS&lt;/code&gt; request before the actual API call. This is called a preflight request and usually happens for “non-simple” requests — for example when using methods like &lt;code&gt;PUT&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt;, but also when adding custom headers.&lt;/p&gt;

&lt;p&gt;And yes, even a completely innocent &lt;code&gt;GET&lt;/code&gt; request can suddenly become &lt;em&gt;two&lt;/em&gt; network calls because somebody added &lt;code&gt;X-Feature-Whatever&lt;/code&gt; three years ago 😅&lt;/p&gt;

&lt;p&gt;In their case, the funniest part was that the custom header wasn’t even used anymore. It was some ancient historical leftover from years earlier. Nobody knew why it existed. Nobody questioned it. It simply survived every refactor like an immortal enterprise relic 😀&lt;/p&gt;

&lt;p&gt;If you’re curious, I actually prepared (together with Claude Code 😅) a small repo showing this behavior here:&lt;br&gt;
&lt;a href="https://github.com/sylwia-lask/preflight-options" rel="noopener noreferrer"&gt;https://github.com/sylwia-lask/preflight-options&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see the screens (please appreciate my high graphic skills!):&lt;/p&gt;

&lt;p&gt;GET request without custom header:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan1gvvc65916s5c2z6rx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan1gvvc65916s5c2z6rx.png" alt="GET request without custom header" width="799" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GET request with custom header:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq92ohavn47hz1gsu2emf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq92ohavn47hz1gsu2emf.png" alt="GET request with custom header containing preflight request" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And honestly, this kind of thing happens &lt;em&gt;all the time&lt;/em&gt; in large projects. Somebody adds a custom header for feature flags, debugging, localization, analytics, or “temporary” metadata… and then the header survives for the next four years.&lt;/p&gt;

&lt;p&gt;Of course, sometimes custom headers are completely justified. But if you only use them for frontend-only logic, there are often better alternatives like query params, cookies, local state, or configuration endpoints fetched once during startup.&lt;/p&gt;

&lt;p&gt;Individually, one extra request may not look catastrophic. But if your app performs dozens of calls during startup, especially on slower mobile connections, this suddenly becomes very noticeable.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Code splitting that does absolutely nothing
&lt;/h2&gt;

&lt;p&gt;Sometimes the problem isn’t the network itself but the gigantic JavaScript bundle we load during startup. And this is usually the moment where everybody says:&lt;/p&gt;

&lt;p&gt;“But how? We’re already doing code splitting! We use lazy loading everywhere!”&lt;/p&gt;

&lt;p&gt;Yeah… about that 😄&lt;/p&gt;

&lt;p&gt;I once audited an Angular application that looked very well structured at first glance. It had modules everywhere, lazy loading, proper architecture, all the “best practices.”&lt;/p&gt;

&lt;p&gt;And yet the application loaded painfully slowly.&lt;/p&gt;

&lt;p&gt;Fortunately, we have tools like &lt;code&gt;webpack-bundle-analyzer&lt;/code&gt;, &lt;code&gt;source-map-explorer&lt;/code&gt;, &lt;code&gt;rollup-plugin-visualizer&lt;/code&gt;, or &lt;code&gt;@next/bundle-analyzer&lt;/code&gt; that allow us to see what’s &lt;em&gt;actually&lt;/em&gt; happening inside our bundles.&lt;/p&gt;

&lt;p&gt;And what did we discover?&lt;/p&gt;

&lt;p&gt;Yes, the application was split into modules…&lt;/p&gt;

&lt;p&gt;…except each module was like 2 KB 😅&lt;/p&gt;

&lt;p&gt;Because almost everything important lived inside one gigantic shared module that was imported absolutely everywhere, meaning most of the application still ended up inside the main bundle anyway 😀&lt;/p&gt;

&lt;p&gt;Congratulations, your app is now split into 400 beautifully separated files that all load at startup.&lt;/p&gt;

&lt;p&gt;This is also not the only weird case I’ve seen. I’ve already encountered situations where the app technically “lazy loaded” modules while still downloading almost the entire application every single time 😄&lt;/p&gt;

&lt;p&gt;For example, something like this looks perfectly fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/admin.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AdminModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks clean. Looks modern. Looks optimized.&lt;/p&gt;

&lt;p&gt;Until you discover that &lt;code&gt;AdminModule&lt;/code&gt; imports a massive shared module containing half the application 😅&lt;/p&gt;

&lt;p&gt;So yeah — just because you use &lt;code&gt;import()&lt;/code&gt; or lazy modules does &lt;em&gt;not&lt;/em&gt; automatically mean your bundles are healthy. Always check what is actually being downloaded by the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Unnecessary runtime dependencies
&lt;/h2&gt;

&lt;p&gt;This is another extremely common problem, especially in projects where nobody really controls what npm packages people install 😅&lt;/p&gt;

&lt;p&gt;In my current project, importing a new dependency is practically treated like a sacred ritual that requires approval from the wisest architects of the kingdom (which basically means me and two or three coworkers 😀). But in many projects, people install libraries completely thoughtlessly.&lt;/p&gt;

&lt;p&gt;And then suddenly your application contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;three analytics SDKs,&lt;/li&gt;
&lt;li&gt;two date libraries,&lt;/li&gt;
&lt;li&gt;all Moment.js locales,&lt;/li&gt;
&lt;li&gt;the entire Lodash package because somebody needed one utility function,&lt;/li&gt;
&lt;li&gt;Firebase imported globally,&lt;/li&gt;
&lt;li&gt;three icon packs,&lt;/li&gt;
&lt;li&gt;and some “tiny lightweight helper package” that quietly imports half the internet 😀&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I once saw an application loading three different date libraries at the same time. The funniest part? The app barely even handled dates 😅 Apparently every developer simply had their own preferred religion.&lt;/p&gt;

&lt;p&gt;Another classic example is importing Lodash like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;debounce&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/debounce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference may look small, but over time these things accumulate &lt;em&gt;a lot&lt;/em&gt;. Especially in enterprise applications that grow for years.&lt;/p&gt;

&lt;p&gt;And unfortunately, tree shaking is not magic 😅&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Huge background images
&lt;/h2&gt;

&lt;p&gt;This one sounds almost too obvious, right?&lt;/p&gt;

&lt;p&gt;Everybody already knows giant images are bad.&lt;/p&gt;

&lt;p&gt;…except people still keep shipping giant images 😄&lt;/p&gt;

&lt;p&gt;Recently, during the WeAreDevelopers podcast, we discussed which government websites loaded the fastest. Surprisingly, the UK completely dominated everybody else. Why? I’ll probably write a separate article about this later, but generally speaking, the site was just extremely simple. Very little visual noise, lots of informational text, simple layout, SSR, minimal unnecessary assets.&lt;/p&gt;

&lt;p&gt;The second fastest was the US government website.&lt;/p&gt;

&lt;p&gt;It followed almost exactly the same principles… except it loaded a fancy large image during startup 😅&lt;/p&gt;

&lt;p&gt;And suddenly the large contentful paint became noticeably worse.&lt;/p&gt;

&lt;p&gt;The funny thing about large background images is that they often look harmless on developer hardware with fast internet. But on slower devices they can absolutely destroy perceived performance.&lt;/p&gt;

&lt;p&gt;Fortunately, there are many ways to improve this: use AVIF or WebP, compress aggressively, avoid massive hero images above the fold, lazy load non-critical visuals, and preload only truly critical assets.&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;Sometimes the fastest image is simply… no image 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Application optimization is obviously an endless topic, and this article only scratches the surface. But I think one of the most important things to understand is that performance problems are often death by a thousand cuts.&lt;/p&gt;

&lt;p&gt;One unnecessary header.&lt;/p&gt;

&lt;p&gt;One oversized dependency.&lt;/p&gt;

&lt;p&gt;One “temporary” shared module.&lt;/p&gt;

&lt;p&gt;One background image nobody questioned.&lt;/p&gt;

&lt;p&gt;Individually, none of these things look catastrophic. Together, they create an application that feels sluggish — especially on older devices or slower mobile networks.&lt;/p&gt;

&lt;p&gt;And the really scary part?&lt;/p&gt;

&lt;p&gt;Most of these decisions looked perfectly reasonable when they were originally introduced 😅&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>react</category>
      <category>frontend</category>
    </item>
    <item>
      <title>I Love Tailwind. Sorry Not Sorry</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Mon, 04 May 2026 08:54:09 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/i-love-tailwind-sorry-not-sorry-5cfh</link>
      <guid>https://dev.to/sylwia-lask/i-love-tailwind-sorry-not-sorry-5cfh</guid>
      <description>&lt;p&gt;I’m going on a short vacation this week, so this post is coming out a bit earlier than usual. I actually had a different, more “useful” topic in mind — something educational, something responsible. But then I came across this fascinating article: &lt;a href="https://dev.to/freshcaffeine/i-dont-like-tailwind-sorry-not-sorry-50b5"&gt;I don’t like Tailwind. Sorry not sorry&lt;/a&gt; written by &lt;a class="mentioned-user" href="https://dev.to/freshcaffeine"&gt;@freshcaffeine&lt;/a&gt; , and I couldn’t get it out of my head.&lt;/p&gt;

&lt;p&gt;So I decided to write a response instead.&lt;br&gt;
Useful content will have to wait 😄&lt;/p&gt;

&lt;p&gt;I actually agree with many of the points in the original article — especially around learning fundamentals. I just have a different perspective shaped by a different kind of work.&lt;/p&gt;

&lt;p&gt;Let me start with a small disclaimer: I’ve written a lot — and I mean &lt;em&gt;a lot&lt;/em&gt; — of handcrafted CSS in my life. Entire design systems. In fact, I got my first job in IT mostly thanks to my CSS skills, because my programming skills at the time were… let’s say “a work in progress” 😉&lt;/p&gt;

&lt;p&gt;There was even a period when I made extra money building simple websites for clients. People literally paid me for delivering clean, aesthetic CSS. &lt;/p&gt;

&lt;p&gt;So in theory, I should be the first person to defend handcrafted CSS and criticize Tailwind for polluting HTML.&lt;/p&gt;

&lt;p&gt;And yet… I’m not.&lt;/p&gt;

&lt;p&gt;Despite all its flaws, I love Tailwind. Deeply, sincerely, and yes — unapologetically.&lt;br&gt;
Because it gives us something incredibly valuable in real-world development: &lt;strong&gt;speed and predictability&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pumpkin pie: homemade or store-bought?
&lt;/h2&gt;

&lt;p&gt;The author of the original article uses a pumpkin pie analogy. Handcrafted CSS is like baking a pie from scratch — roasting the pumpkin, making the dough, carefully preparing everything with love. Tailwind, on the other hand, is like using pre-made ingredients. You open a can, use ready-made crust, assemble everything quickly. Sure, it’s still a pie, but not quite like the one your grandma would make.&lt;/p&gt;

&lt;p&gt;It’s a nice analogy. It really is.&lt;/p&gt;

&lt;p&gt;The problem is — most businesses are not running artisan bakeries.&lt;br&gt;
They’re running factories.&lt;br&gt;
And those factories aren’t even in the pie business.&lt;/p&gt;

&lt;p&gt;In reality, business rarely needs a handcrafted pie. Honestly, it often doesn’t even need a “semi-handmade” one. What it really wants is mass production: something that’s sweet enough, looks good enough, doesn’t cause stomachache, and can be delivered fast. If you can add a small decorative touch on top to make it feel slightly more unique — great. But even that is optional.&lt;/p&gt;

&lt;p&gt;And there’s no point being offended by this. We can absolutely build beautiful, handcrafted CSS when we want to. But most of the time, businesses choose speed — because they are selling a product, not CSS.&lt;/p&gt;

&lt;p&gt;I’m not building a piece of art.&lt;br&gt;
I’m building software that five teams won’t break next week.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repetition isn’t always a bug
&lt;/h2&gt;

&lt;p&gt;One of the arguments against Tailwind is that everything starts to look the same. And honestly — that’s true.&lt;/p&gt;

&lt;p&gt;But here’s the thing: very often, that’s exactly what the client wants.&lt;/p&gt;

&lt;p&gt;Back when I was building websites for clients, the happiest ones were those who got three templates to choose from and a bit of customization on top. They didn’t want a masterpiece. They wanted something clean, modern, and effective — something that sells.&lt;/p&gt;

&lt;p&gt;Tailwind is often simply &lt;em&gt;good enough&lt;/em&gt; for that.&lt;/p&gt;

&lt;p&gt;And in many cases, &lt;strong&gt;good enough delivered fast beats perfect delivered late&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  “Messy HTML”
&lt;/h2&gt;

&lt;p&gt;Yes — if you just throw classes around randomly, your HTML will look messy.&lt;/p&gt;

&lt;p&gt;But let’s be honest: if we’re “craft-oriented developers,” we can organize our components properly, right? In real projects, that long Tailwind class list usually lives inside a component anyway. You don’t copy-paste that everywhere.&lt;/p&gt;

&lt;p&gt;Also:&lt;/p&gt;

&lt;p&gt;HTML is “noisy”? Sure.&lt;br&gt;
But at least the rules are right next to what they affect.&lt;/p&gt;

&lt;p&gt;I’ve seen plenty of “beautiful” CSS codebases where styling logic was scattered across multiple files, overridden in unexpected places, and impossible to trace without jumping through five layers of abstraction. I’ll take explicit over “hidden magic” any day.&lt;/p&gt;




&lt;h2&gt;
  
  
  Junior developers and “not learning CSS”
&lt;/h2&gt;

&lt;p&gt;I actually agree with one part: Tailwind doesn’t replace learning CSS. I even wrote about that in my article: &lt;a href="https://dev.to/sylwia-lask/is-learning-css-a-waste-of-time-in-2026-nj3"&gt;Is Learning CSS a Waste of Time in 2026?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the argument that Tailwind is somehow “hurting juniors” always makes me smile a bit.&lt;/p&gt;

&lt;p&gt;On one hand, we have mass layoffs in tech and endless discussions about AI replacing developers. On the other, we worry that juniors might not learn CSS because things are… too easy?&lt;/p&gt;

&lt;p&gt;Let’s be real for a second.&lt;/p&gt;

&lt;p&gt;“Junior” doesn’t mean “child.” These are adults. If someone wants to grow as a frontend developer, learning CSS is part of the job. It’s not some hidden, mystical knowledge. And we don’t need to choose our entire tech stack based on making things harder just so people are forced to learn.&lt;/p&gt;

&lt;p&gt;Also — I’ve seen plenty of experienced developers who still struggle with CSS after years in the industry. At that point, I’d honestly rather have them use Tailwind and ship something consistent than fight yet another specificity war.&lt;/p&gt;

&lt;p&gt;Tailwind doesn’t create bad developers.&lt;br&gt;
Lack of fundamentals does.&lt;/p&gt;




&lt;h2&gt;
  
  
  About “craft”
&lt;/h2&gt;

&lt;p&gt;There’s this idea that writing CSS is a form of craftsmanship — something closer to art, something deeply satisfying.&lt;/p&gt;

&lt;p&gt;And yes, it can be.&lt;/p&gt;

&lt;p&gt;But the last few years — especially with the rise of LLMs — have made it pretty clear where our “craft” actually sits in the bigger picture. In most business applications, CSS is not art. It’s not painting. It’s not sculpture.&lt;/p&gt;

&lt;p&gt;It’s closer to baking pumpkin pies at scale.&lt;/p&gt;

&lt;p&gt;There will always be places where handcrafted work matters — just like there are bakeries selling beautiful, artisanal cakes. But if you’re selling paper clips and organizing a corporate event, you’re probably not baking everything from scratch. You’re ordering something decent that gets the job done.&lt;/p&gt;

&lt;p&gt;And that’s fine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I actually like Tailwind
&lt;/h2&gt;

&lt;p&gt;Let’s be clear — Tailwind is not perfect. It has trade-offs.&lt;/p&gt;

&lt;p&gt;But it solves very real problems.&lt;/p&gt;

&lt;p&gt;It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;speed&lt;/strong&gt; — you don’t context-switch between files every 10 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;predictability&lt;/strong&gt; — no guessing what some class name means&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;consistency&lt;/strong&gt; — especially across large teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;simple selectors&lt;/strong&gt; — which are often easier for browsers to process than deeply nested CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;less dead code&lt;/strong&gt; — thanks to modern build setups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;It removes ambiguity.&lt;/p&gt;

&lt;p&gt;The real problem in large codebases isn’t that CSS isn’t “beautiful” enough.&lt;br&gt;
It’s that it becomes inconsistent, fragile, and slow to evolve.&lt;/p&gt;

&lt;p&gt;I’ve never seen a project fail because CSS wasn’t handcrafted enough.&lt;br&gt;
I’ve seen plenty fail because things were inconsistent and took forever to build.&lt;/p&gt;




&lt;h2&gt;
  
  
  When handcrafted CSS still makes sense
&lt;/h2&gt;

&lt;p&gt;I don’t think Tailwind (or something similar) should replace handcrafted CSS everywhere.&lt;/p&gt;

&lt;p&gt;There are cases where writing CSS by hand is not just useful — it’s the better choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design systems and shared UI foundations&lt;/strong&gt; — where you need full control and long-term consistency&lt;br&gt;
&lt;strong&gt;Highly custom or experimental UI&lt;/strong&gt; — where utility classes start to fight you instead of helping&lt;br&gt;
&lt;strong&gt;Performance-critical interfaces&lt;/strong&gt; — where you want precise control over what gets shipped&lt;br&gt;
&lt;strong&gt;Learning and understanding the fundamentals&lt;/strong&gt; — because at some point, abstractions always leak&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Tailwind isn’t about replacing CSS.&lt;br&gt;
It’s about making frontend development survivable at scale.&lt;/p&gt;

&lt;p&gt;And no — this post is not sponsored by Tailwind. (But if someone from Tailwind happens to read this… feel free to reach out 😄)&lt;/p&gt;

&lt;p&gt;And what do you guys think? Are you Team Tailwind or more into 'craft' CSS? Or maybe something in between?&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you enjoyed this post, I'd love to have you follow me here on &lt;a href="https://www.linkedin.com/in/sylwia-laskowska-5a8467131/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>css</category>
      <category>tailwindcss</category>
      <category>frontend</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Is Software Development Just a Side Quest? A Jira Story</title>
      <dc:creator>Sylwia Laskowska</dc:creator>
      <pubDate>Thu, 30 Apr 2026 06:01:20 +0000</pubDate>
      <link>https://dev.to/sylwia-lask/is-software-development-just-a-side-quest-a-jira-story-4ng3</link>
      <guid>https://dev.to/sylwia-lask/is-software-development-just-a-side-quest-a-jira-story-4ng3</guid>
      <description>&lt;p&gt;How much time did you spend this week moving tickets in Jira (or other tracking tool) instead of actually coding?&lt;/p&gt;

&lt;p&gt;I sometimes have this feeling that my main job is not development anymore — it’s just moving things between columns.&lt;/p&gt;

&lt;p&gt;I always say that a software developer, by nature, is lazy. That’s why we became developers in the first place — to automate everything. So maybe expecting us to not only do our actual work, but also carefully maintain every single detail in Jira… is a bit optimistic.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick “what’s up with me” section. My recent article&lt;br&gt;
&lt;a href="https://dev.to/sylwia-lask/most-apps-are-slower-than-they-need-to-be-heres-why-live-demo-2hh8"&gt;Most Apps are Slower Than They Need To Be&lt;/a&gt;&lt;br&gt;
ended up going way beyond DEV — different newsletters, and it even got me invited to a podcast at &lt;a href="https://www.youtube.com/watch?v=qE4QmV1EIDc" rel="noopener noreferrer"&gt;WeAreDevelopers&lt;/a&gt; 🎤 First podcast in my life. Chaos, tangents… pretty much 100% me 😅&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And here’s a fun part: the technical article that opened those doors had almost 6x fewer views than this one:&lt;br&gt;
&lt;a href="https://dev.to/sylwia-lask/youre-a-real-software-developer-only-if-2mo8"&gt;You're a Real Software Developer Only If...&lt;/a&gt; Well, turns out we all enjoy a good laugh more than GPU acceleration demos. Can’t argue with reality 😄&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyway, back to the topic.&lt;/p&gt;

&lt;p&gt;I’m a senior developer. Not officially a tech lead in my current company, but in practice I do a lot of that work, next to coding. Coordinating developers' work, answering questions, helping unblock people. And it’s not just the team — there are stakeholders, testers, other teams.&lt;/p&gt;

&lt;p&gt;And the app? It’s a government system. So if something breaks, it’s not “oh no, someone couldn’t watch a show” (haha yes, I'm refering to &lt;a class="mentioned-user" href="https://dev.to/adamthedeveloper"&gt;@adamthedeveloper&lt;/a&gt; and his famous &lt;a href="https://dev.to/adamthedeveloper/youre-not-building-netflix-stop-coding-like-you-are-1707"&gt;You're Not Building Netflix&lt;/a&gt; post 😁). The consequences can be very real.&lt;/p&gt;

&lt;p&gt;After a day like that, the last thing I feel like doing is carefully updating every field in Jira.&lt;/p&gt;

&lt;p&gt;Don’t get me wrong — I actually like having a tracking tool. I can’t imagine working without one, especially in a bigger team. Tasks need to exist somewhere, priorities need to be visible, things shouldn’t disappear into Slack threads.&lt;/p&gt;

&lt;p&gt;I also create tickets myself all the time, or ask for them to be created. I want things tracked. I want a history. I want clarity.&lt;/p&gt;

&lt;p&gt;But for me, a ticket should have three states: todo, in progress, done.&lt;/p&gt;

&lt;p&gt;Everything else is… negotiable.&lt;/p&gt;

&lt;p&gt;Stories? Epics? Fine. If it helps someone manage the process, I can live with that.&lt;/p&gt;

&lt;p&gt;But then come the extra fields. The additional statuses. The “just one more thing” because it will make the report nicer. Because the burn-down chart will look better. Because someone somewhere wants a cleaner dashboard.&lt;/p&gt;

&lt;p&gt;And slowly, without really noticing, we turn Jira into something that requires more mental effort than the actual development.&lt;/p&gt;

&lt;p&gt;We’re basically the boiling frog at this point. One more field. One more status. One more small tweak. Until suddenly nobody really knows what goes where anymore, what needs to be updated, and why.&lt;/p&gt;

&lt;p&gt;And then, of course, developers get blamed for “not keeping Jira up to date”.&lt;/p&gt;

&lt;p&gt;At some point it starts feeling like development itself is just a side quest. If we didn’t have to deal with code at all, imagine how perfect our Jira boards could be. Beautiful burn-down charts. Perfectly filled tickets. Absolute harmony 😄&lt;/p&gt;

&lt;p&gt;The funny thing is — the best developers I know are often the ones who engage with this the least. Not because they don’t care, but because their focus is somewhere else. On solving real problems.&lt;/p&gt;

&lt;p&gt;I’m still managing it somehow. But I definitely feel the friction.&lt;/p&gt;

&lt;p&gt;So I’m curious — is it just me?&lt;/p&gt;

&lt;p&gt;Do you also feel this kind of frustration sometimes? Or did you actually manage to find a system that works without turning Jira into a full-time job?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
