<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Paolo Longo</title>
    <description>The latest articles on Forem by Paolo Longo (@paolimi).</description>
    <link>https://forem.com/paolimi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F388949%2F8febe1e7-9d94-42d6-a21a-792f707d1fe8.png</url>
      <title>Forem: Paolo Longo</title>
      <link>https://forem.com/paolimi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/paolimi"/>
    <language>en</language>
    <item>
      <title>TypeScript: a new Frontier for Error Management</title>
      <dc:creator>Paolo Longo</dc:creator>
      <pubDate>Tue, 01 Oct 2024 12:22:42 +0000</pubDate>
      <link>https://forem.com/paolimi/typescript-a-new-frontier-for-error-management-4li7</link>
      <guid>https://forem.com/paolimi/typescript-a-new-frontier-for-error-management-4li7</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;(Article originally written on &lt;a href="https://levelup.gitconnected.com/typescript-a-new-frontier-for-error-management-90db81bec30b" rel="noopener noreferrer"&gt;Level Up Coding&lt;/a&gt;.)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You're working on your TypeScript project. The code is &lt;strong&gt;clean&lt;/strong&gt; and &lt;strong&gt;well-architected&lt;/strong&gt;, you're proud of it. One day, an &lt;em&gt;error&lt;/em&gt; pops up. Its stack trace stretches longer than the average npm install, bubbling up through countless layers that failed to handle it. Your code &lt;strong&gt;doesn't work&lt;/strong&gt;, you have no idea where to start fixing it, every attempt feels like a &lt;strong&gt;clumsy patch&lt;/strong&gt;. Your architecture doesn't look so clean anymore. You hate your project. You close your PC and go to enjoy your &lt;em&gt;Friday&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Error Management Wasteland
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2Foxg94810becp5nvbg3o9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Foxg94810becp5nvbg3o9.jpg" alt="Wasteland" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript's &lt;strong&gt;error management&lt;/strong&gt; falls short of the expressive power and developer experience offered by modern languages like Rust, Zig, and Go. Its dynamic nature and lack of guardrails often leave developers navigating uncertainty, without the solid foundations and guarantees that stricter platforms provide.&lt;/p&gt;

&lt;p&gt;This crucial pillar of software engineering is poorly reflected in the language's &lt;strong&gt;culture&lt;/strong&gt; and &lt;strong&gt;ecosystem&lt;/strong&gt;, with some of the most popular npm libraries failing to even mention exceptions in their documentation.&lt;/p&gt;

&lt;p&gt;This lack of standards fosters in developers the &lt;strong&gt;misconception&lt;/strong&gt; that exceptions rarely occur. As a result, this skewed perspective leads to a lack of interest in establishing such standards within the community, and ultimately riddles most codebases with subtle, hard-to-spot bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try-Catch: the Costs of Implicitness
&lt;/h2&gt;

&lt;p&gt;The JavaScript try-catch model hides &lt;strong&gt;non-obvious implications&lt;/strong&gt;. Exceptions can occur anywhere, yet anticipating them is surprisingly challenging. This seemingly simple pattern often obscures subtle pitfalls in everyday code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mayThrow&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="c1"&gt;// Handle the exception.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first issue that stands out in the snippet is the &lt;strong&gt;scope expansion&lt;/strong&gt;, with variables needing to be declared outside the try-catch block to maintain a contiguous control flow. This leads to more &lt;strong&gt;verbose&lt;/strong&gt;, &lt;strong&gt;harder-to-track&lt;/strong&gt; code, potentially introducing subtle bugs as the codebase grows in complexity.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;implicit&lt;/strong&gt; nature of this dynamic error handling increases the &lt;strong&gt;cognitive load&lt;/strong&gt; on the developers, requiring them to mentally track exception sources throughout the codebase. In contrast, explicit error handling models, like for instance the one in Go, &lt;strong&gt;compel&lt;/strong&gt; developers to acknowledge and handle any error.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mayFail&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is a huge win in the long term, facilitating smoother and safer maintenance as projects evolve.&lt;/p&gt;

&lt;p&gt;Adding to these challenges, TypeScript's catch clause falls short in its ability to track and strictly type the errors that can be thrown, resulting in a &lt;strong&gt;loss of type safety&lt;/strong&gt; at precisely when it's most crucial. JavaScript even allows throwing non-Error values, leaving us with practically no safeguards. Languages like Rust &lt;a href="https://doc.rust-lang.org/book/ch09-00-error-handling.html" rel="noopener noreferrer"&gt;showcase&lt;/a&gt; the power and elegance that a stricter model can provide:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;may_fail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PermissionDenied&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Permission denied"&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;Various proposals have been submitted to the TypeScript team, aiming to establish a foundation for a more robust and predictable exception system. However, these proposals have often been &lt;strong&gt;blocked by limitations&lt;/strong&gt; in the underlying JavaScript platform, which lacks the necessary primitives to support such architectural enhancements.&lt;/p&gt;

&lt;p&gt;Meanwhile, some proposals to address these shortcomings have also been submitted to TC39 &lt;em&gt;(the committee for ECMAScript standardization)&lt;/em&gt;, but they remain in the early stages of consideration. As Matt Pocock pointed out, the heat death of the universe is also making steady progress.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1824338426058957098-425" src="https://platform.twitter.com/embed/Tweet.html?id=1824338426058957098"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1824338426058957098-425');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1824338426058957098&amp;amp;theme=dark"
  }



&lt;/p&gt;
&lt;h2&gt;
  
  
  Seeking Community Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2F83pen5byxrrp2eytl5z4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F83pen5byxrrp2eytl5z4.jpg" alt="chess pawns with different color gradations" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a language creates friction for innovation, the developer community often responds with ingenious libraries and user-land solutions. Many of the current proposals in this domain, like the exceptional &lt;em&gt;&lt;a href="https://github.com/supermacro/neverthrow" rel="noopener noreferrer"&gt;Neverthrow&lt;/a&gt;&lt;/em&gt;, draw inspiration from &lt;strong&gt;functional programming&lt;/strong&gt;, offering a suite of abstractions and utilities similar to Rust's &lt;code&gt;Result&lt;/code&gt; type to address the problem:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mayFail&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;condition&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="nf"&gt;err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&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="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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;Another approach that stands out is the one of &lt;em&gt;&lt;a href="https://effect.website/" rel="noopener noreferrer"&gt;Effect&lt;/a&gt;&lt;/em&gt;. This powerful toolkit not only tackles error management head-on but also provides a comprehensive suite of utilities for handling asynchronous operations, resource management, and more:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;effect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Error&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;return&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;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;Cannot divide by zero&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="nx"&gt;Effect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;succeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;b&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Outside the joy of a nerd like myself in digging into tech like this, adopting new technologies demands a careful &lt;strong&gt;cost-benefit analysis&lt;/strong&gt;. The JavaScript ecosystem evolves at a breakneck pace, with libraries emerging and becoming obsolete in rapid succession.&lt;/p&gt;

&lt;p&gt;Choosing the wrong abstraction can hold your code hostage, create friction in your development process, and demand &lt;strong&gt;blood, sweat, and tears&lt;/strong&gt; to migrate away from. &lt;em&gt;(Also, adding a new package is likely not gonna help with the 200mb bundle size of your React app.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Error management is a pervasive concern that touches nearly every part of a codebase. Any abstraction that requires &lt;strong&gt;rethinking&lt;/strong&gt; and &lt;strong&gt;rewriting&lt;/strong&gt; such a vast expanse of code demands an enormous amount of trust—perhaps even &lt;em&gt;faith&lt;/em&gt;—in its design.&lt;/p&gt;
&lt;h2&gt;
  
  
  Crafting a Path Forward
&lt;/h2&gt;

&lt;p&gt;We've explored the limitations of user-land solutions, and life's too short to await commit approvals for new syntax proposals. Could there be a middle ground? What if we could &lt;strong&gt;push the boundaries&lt;/strong&gt; of what's currently available in the language, creating something that aspires to be a new standard or part of the standard library, yet is written entirely in user-land and we can use it right now?&lt;/p&gt;

&lt;p&gt;As we delve into this concept, let's consider some key principles that could shape our idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conventions over Abstractions&lt;/strong&gt;: Minimize abstractions by leveraging existing language features to their fullest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal API&lt;/strong&gt;: Strive for simplicity without sacrificing functionality. Conciseness is often an indicator of robust and lasting design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility and Integrability&lt;/strong&gt;: Our solution shouldn't depend on universal adoption, and must seamlessly consume and be consumed by code not written with the same principles in mind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intuitive and Ergonomic&lt;/strong&gt;: The patterns should be self-explanatory, allowing developers to grasp and implement them at a glance, minimizing the risk of misinterpretations that could result in anti-patterns or unexpected behaviors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exploit TypeScript&lt;/strong&gt;: Leverage TypeScript's type system to provide immediate feedback through IDE features like syntax highlighting, error detection, and auto-completion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's dive into the heart of the matter by addressing our first key challenge. Let's introduce the term &lt;code&gt;task&lt;/code&gt; for functions that may either succeed or encounter an error.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&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="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&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;failed&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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;We need an error-handling approach that keeps control flow &lt;strong&gt;clean&lt;/strong&gt;, keeps developers constantly &lt;strong&gt;aware&lt;/strong&gt; of potential failures, and maintains &lt;strong&gt;type safety&lt;/strong&gt; throughout. One idea worth exploring is the concept of returning errors instead of throwing them. Let's see how this might look:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&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="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// return instead of throwing.&lt;/span&gt;
    &lt;span class="k"&gt;return&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;failed&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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;By introducing Errors as values and assigning them specific meaning, we enhance the expressivity of a task's return value, which can now represents either successful or failing outcomes. TypeScript’s type system becomes particularly effective here, typing the result as &lt;code&gt;string | Error&lt;/code&gt;, and flagging any attempt to use the result without first checking for errors. This ensures safer code practices. Once error checks are performed, &lt;strong&gt;type narrowing&lt;/strong&gt; allows us to work with the success value free from the Error type.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Handle the error.&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;result&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;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ?^ result: string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Managing multiple errors becomes &lt;strong&gt;reliable&lt;/strong&gt; with TypeScript’s type checker, which guides the process through &lt;strong&gt;autocompletion&lt;/strong&gt; and catches mistakes at compile time, ensuring a type-driven and dependable workflow.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&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="nx"&gt;condition1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomError1&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;condition2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomError2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In another file...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;task&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;result&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;CustomError1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle CustomError1.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;result&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;CustomError2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle CustomError2.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And since we're just working within plain JavaScript, we can seamlessly integrate existing libraries to enhance our error handling. For example, the powerful &lt;em&gt;&lt;a href="https://github.com/gvergnaud/ts-pattern" rel="noopener noreferrer"&gt;ts-pattern&lt;/a&gt;&lt;/em&gt; library synergize beautifully with this approach:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ts-pattern&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CustomError1&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="cm"&gt;/* Handle CustomError1 */&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CustomError2&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="cm"&gt;/* Handle CustomError2 */&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;otherwise&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="cm"&gt;/* Handle success case */&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We now face &lt;strong&gt;2 types&lt;/strong&gt; of errors: those &lt;strong&gt;returned&lt;/strong&gt; by tasks adopting our convention and those &lt;strong&gt;thrown&lt;/strong&gt;. As established in our guiding principles, we can't assume every function will follow our convention. This assumption is not only necessary to make our pattern useful and usable, but it also reflects the reality of JavaScript code. Even without explicit throws, runtime errors like &lt;em&gt;"cannot read properties of null"&lt;/em&gt; can still occur unexpectedly.&lt;/p&gt;

&lt;p&gt;Within our convention, we can classify returned errors as &lt;strong&gt;"expected"&lt;/strong&gt; — these are errors we can anticipate, handle, and recover from. On the other hand, thrown errors belong to the &lt;strong&gt;"unexpected"&lt;/strong&gt; category — errors we can't predict or generally  recover from. These are best addressed at the highest levels of our program, primarily for logging or general awareness. Similar distinctions are built into the syntax of some other languages. For example, in Rust:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Recoverable error.&lt;/span&gt;
&lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task failed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Unrecoverable error.&lt;/span&gt;
&lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fatal error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For third-party APIs whose errors we want to handle, we can &lt;strong&gt;wrap&lt;/strong&gt; them in our own functions that conform to our error handling convention. This approach also gives us the opportunity to add additional context or transform the error into a more meaningful representation for our specific use case. Let's take fetch as an example, to demonstrate also how this pattern seamlessly extends to asynchronous functions:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;$fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;RequestInit&lt;/span&gt;&lt;span class="p"&gt;)&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="c1"&gt;// Make the request.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&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="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Return the response if it's OK, otherwise an error.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ?^ DOMException | TypeError | SyntaxError.&lt;/span&gt;
    &lt;span class="c1"&gt;// Any cause from request abortion to a network error.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RequestError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When fetch returns a response with a non-2XX status code, it's often considered an unexpected result from the client's perspective, as it falls outside the normal flow. We can wrap such responses in a custom exception type (&lt;code&gt;ResponseError&lt;/code&gt;), while keeping other network or parsing issues in their own type (&lt;code&gt;RequestError&lt;/code&gt;).&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ResponseError&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;RequestError&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;/api&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;This is an example of how we can wrap third-party APIs to enrich the expressiveness of their error handling. This approach also allows for &lt;strong&gt;progressive enhancement&lt;/strong&gt; — whether you’re incrementally refactoring existing try/catch blocks or just starting to add proper error types in a codebase that’s never even heard of try/catch. &lt;em&gt;(Yes, we know you’re out there.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another important aspect to consider is &lt;strong&gt;task composition&lt;/strong&gt;, where we need to extract the results from multiple tasks, process them, and return a new value. In case any task returns an error, we simply stop the execution and propagate it back to the caller. This kind of task composition can look 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Compute the result and exclude the error.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Error1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;task1&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;result1&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Error1&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;result1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Compute the result and exclude the error.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Error2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;task2&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;result2&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Error2&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;result2&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;result2&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 return type of the task is correctly inferred as &lt;code&gt;number | Error1 | Error2&lt;/code&gt;, and type narrowing allow removing the &lt;code&gt;Error&lt;/code&gt; types from the return values. It works, but it's not very concise. To address this issue, languages like Zig have a dedicated operator:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;mayFail&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can achieve something similar in TypeScript with a few simple tricks. Our goal is to create a more concise and readable way of handling errors while maintaining type safety. Let's attempt to define a similar utility function which we'll call &lt;code&gt;$try&lt;/code&gt;, it could look something 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&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;result1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;task1&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;result2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;task2&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;result1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;result2&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;This code looks definitely cleaner and more straightforward. Internally, the function could be implemented 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;$try&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Error&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;result&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="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&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;$try&lt;/code&gt; function takes a result of type &lt;code&gt;T&lt;/code&gt;, checks if it's an &lt;code&gt;Error&lt;/code&gt;, and throws it if so. Otherwise, it returns the result, with TypeScript inferring the return type as &lt;code&gt;Exclude&amp;lt;T, Error&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We've gained a lot in readability and clarity, but we've &lt;strong&gt;lost the ability to type expected errors&lt;/strong&gt;, moving them to the &lt;strong&gt;unexpected&lt;/strong&gt; category. This isn't ideal for many scenarios.&lt;/p&gt;

&lt;p&gt;We need a native way to &lt;strong&gt;collect the errors types&lt;/strong&gt;, perform &lt;strong&gt;type narrowing&lt;/strong&gt;, and &lt;strong&gt;terminate execution&lt;/strong&gt; if an error occurs, but we are running short on JavaScript constructs. Fortunately, &lt;code&gt;Generators&lt;/code&gt; can come to our rescue. Though often overlooked, they can effectively handle complex control flow problems.&lt;/p&gt;

&lt;p&gt;With some clever coding, we can use the &lt;code&gt;yield&lt;/code&gt; keyword to extract the return type from our tasks. &lt;code&gt;yield&lt;/code&gt; passes control to another process that determines whether to terminate execution based on whether an error is present. We’ll refer to this functionality as &lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html" rel="noopener noreferrer"&gt;&lt;code&gt;$macro&lt;/code&gt;&lt;/a&gt;, as if it extends the language itself:&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="c1"&gt;// ?^ result: number | Error1 | Error2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$macro&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$try&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;result1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;$try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;task1&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;result2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;$try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;task2&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;result1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;result2&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;We'll discuss the implementation details later. For now, we've achieved our compact syntax at the cost of introducing an utility. It accepts tasks following our convention and returns a result with the same convention: this ensures the abstraction remains &lt;strong&gt;confined&lt;/strong&gt; to its intended scope, preventing it from leaking into other parts of the codebase — neither in the caller nor the callee.&lt;/p&gt;

&lt;p&gt;As it's still possible to have the &lt;strong&gt;"vanilla"&lt;/strong&gt; version with if statements, paying for slightly higher verbosity, we've struck a good balance between conciseness and keeping everything with no abstraction. Moreover, we've got a potential starting point to &lt;strong&gt;inspire&lt;/strong&gt; new syntax or a new part of the standard library, but that's for another post and the ECMAScript committee will have to wait for now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Our journey could end here: we've highlighted the limitations of current error management practices in JavaScript, introduced a convention that cleanly separates expected from unexpected errors, and tied everything together with strong type definitions.&lt;/p&gt;

&lt;p&gt;As obvious as it may seems, the real strength of this approach lies in the fact that most JavaScript functions are just a particular case of this convention, that happens to return no expected error. This makes integrating with code written without this convention in mind as intuitive and seamless as possible.&lt;/p&gt;

&lt;p&gt;One last enhancement we can introduce is simplifying the handling of unexpected errors, which up to now still requires the use of try/catch. The key is to clearly distinguish between the task result and unexpected errors. Taking inspiration from Go's error-handling pattern, we can achieve this using a utility like:&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$trycatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This utility adopts a Go-style tuple approach, where the first element is the task's result, and the second contains any unexpected error. Exactly one of these values will be present, while the other will be &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But we can take it a step further. By leveraging TypeScript's type system, we can ensure that the task's return type remains &lt;code&gt;unknown&lt;/code&gt; until the error is explicitly checked and handled. This prevents the accidental use of the &lt;code&gt;result&lt;/code&gt; while an error is present:&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$trycatch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;succeed!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ?^ result: unknown&lt;/span&gt;
&lt;span class="c1"&gt;// ?^ err: Error | null&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;err&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ?^ result: string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Due to JavaScript's dynamic nature, any type of value can be thrown. To avoid falsy values that can create and subtle bugs when checking for the presence of an error, &lt;code&gt;err&lt;/code&gt; will be an &lt;code&gt;Error&lt;/code&gt; object that encapsulates the thrown values and expose them through &lt;code&gt;Error.cause&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To complete out utility, we can extend it to handle asynchronous functions and promises, allowing the same pattern to be applied to asynchronous operations:&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="c1"&gt;// Async functions.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;]&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;$trycatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="c1"&gt;// Or Promises.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;]&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;$trycatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(...));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's enough for today. I hope you’ve enjoyed the journey and that this work inspires new innovations in the Javascript and Typescript ecosystem.&lt;/p&gt;

&lt;p&gt;How to implement the code in the articles, you ask? Well, of course there's a library! Jokes aside, the code is straightforward, but the real value lies in the design and thought process behind it. The &lt;strong&gt;repository&lt;/strong&gt; serves as a foundation for ongoing discussions and improvements. Feel free to contribute or share your thoughts!&lt;/p&gt;

&lt;p&gt;See you next time — peace ✌️.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ts-zen" rel="noopener noreferrer"&gt;
        ts-zen
      &lt;/a&gt; / &lt;a href="https://github.com/ts-zen/trycatch" rel="noopener noreferrer"&gt;
        trycatch
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Robust and Type-Safe Errors Management Conventions with Typescript
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;br&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/ts-zen/trycatch/refs/heads/main/docs/statics/logo.svg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fts-zen%2Ftrycatch%2Frefs%2Fheads%2Fmain%2Fdocs%2Fstatics%2Flogo.svg" width="40%"&gt;&lt;/a&gt; &lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Robust&lt;/strong&gt; and &lt;strong&gt;Type-Safe&lt;/strong&gt; Errors Management &lt;strong&gt;Conventions&lt;/strong&gt; with &lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;Typescript&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5598b15488e625474a68e72d33dede4c0cacd6cff8bf5d0f6c05b7dcf2f49668/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74797065732d547970657363726970742d3331373843363f7374796c653d666c61742d737175617265266c6f676f3d74797065736372697074" alt="types: Typescript"&gt;&lt;/a&gt;
&lt;a href="https://github.com/ts-zen/trycatch/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/458d536f342016668ea6b7506c38ee777777f14f49720c43098ee626f355196a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f74732d7a656e2f74727963617463682f63692e796d6c3f7374796c653d666c61742d737175617265266272616e63683d6d61696e" alt="Github CI"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/ts-zen/trycatch" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eac36fa6e7859a45731175d22c72f202b4b85d0982d6c2069081c21f61f029d8/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f74732d7a656e2f74727963617463683f636f6c6f723d343463633131266c6f676f3d636f6465636f76267374796c653d666c61742d737175617265" alt="Codecov"&gt;&lt;/a&gt;
&lt;a href="https://prettier.io/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5c09bbf779b7458724d7fbdab6c613c5b87defb1717337da05cfe641761bc0c7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d50726574746965722d6666363962342e7376673f7374796c653d666c61742d737175617265266c6f676f3d7072657474696572" alt="code style: Prettier"&gt;&lt;/a&gt;
&lt;a href="http://npm.im/@tszen/trycatch" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d92efae6d91d5b3db0dd2b2b346200d72ec321ee792f6d140198bf31e095191c/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4074737a656e2f74727963617463682e7376673f7374796c653d666c61742d737175617265" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://bundlejs.com/?q=@tszen/trycatch" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e7f37eb04513664326bebca9ece26e53c87fa8039e8553b36aa099e8a06b6e85/68747470733a2f2f696d672e736869656c64732e696f2f62756e646c656a732f73697a652f4074737a656e2f74727963617463683f7374796c653d666c61742d737175617265266c6162656c3d73697a65266c6f676f3d65736275696c6426636f6c6f723d464643463030" alt="Bundle Size"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/ts-zen/trycatch/refs/heads/main/docs/statics/example-dark.png#gh-dark-mode-only"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fts-zen%2Ftrycatch%2Frefs%2Fheads%2Fmain%2Fdocs%2Fstatics%2Fexample-dark.png%23gh-dark-mode-only" width="80%"&gt;&lt;/a&gt; &lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/ts-zen/trycatch/refs/heads/main/docs/statics/example-light.png#gh-light-mode-only"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fts-zen%2Ftrycatch%2Frefs%2Fheads%2Fmain%2Fdocs%2Fstatics%2Fexample-light.png%23gh-light-mode-only" width="80%"&gt;&lt;/a&gt; &lt;br&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Philosophy&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Haven’t read the blog post yet? You can find it &lt;a href="https://dev.to/paolimi/typescript-a-new-frontier-for-error-management-4li7" rel="nofollow"&gt;here&lt;/a&gt; for a deep dive into the design and reasoning behind this project. Here's a quick snapshot to get you started:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JavaScript’s &lt;strong&gt;error management&lt;/strong&gt; falls short of the expressive power and developer experience offered by modern languages like Rust, Zig, and Go. Language design is hard, and most proposals to the ECMAScript or TypeScript committees are either rejected or move through an extremely slow iteration process.&lt;/p&gt;

&lt;p&gt;Most libraries and user-land solutions in this area introduce abstractions that fall into the red/blue function problem, requiring full codebase adoption and resulting in technology lock-in.&lt;/p&gt;

&lt;p&gt;The goal of this project is to push the boundaries of error handling in JavaScript, prioritizing &lt;strong&gt;conventions over abstractions&lt;/strong&gt; and leveraging native constructs to their fullest potential. We provide a minimal set of utilities to enhance developer experience, with…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ts-zen/trycatch" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Aviator🎮  -  Test your coding and logic skills with a web game</title>
      <dc:creator>Paolo Longo</dc:creator>
      <pubDate>Sat, 20 Jun 2020 14:58:45 +0000</pubDate>
      <link>https://forem.com/paolimi/theaviator-test-your-coding-and-logic-skills-with-a-web-game-24b8</link>
      <guid>https://forem.com/paolimi/theaviator-test-your-coding-and-logic-skills-with-a-web-game-24b8</guid>
      <description>&lt;p&gt;I've always liked challenges and problem-solving. This is the reason that made me embark on a journey into the world of programming.&lt;/p&gt;

&lt;p&gt;It started when I was 15, in the high school computer science course, where I wrote my first &lt;em&gt;&lt;code&gt;"Hello World"&lt;/code&gt;&lt;/em&gt;. Looking back, I can see the most significant &lt;strong&gt;stages&lt;/strong&gt; passed so far, in which I have improved, matured, and in which I can identify a &lt;em&gt;before&lt;/em&gt; and &lt;em&gt;after&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now I study computer engineering at university, and I feel I have reached another important stage of this journey. Stage that I want to represent with a project, to test myself and the skills I have gained.&lt;/p&gt;

&lt;p&gt;And so was born &lt;em&gt;The Aviator&lt;/em&gt;, a coding game for folks like me who like to test themselves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FPaol-imi%2Fthe-aviator%2Fblob%2Fmaster%2Fimages%2Fscreens%2Fworlds.gif%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FPaol-imi%2Fthe-aviator%2Fblob%2Fmaster%2Fimages%2Fscreens%2Fworlds.gif%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 worlds compose the game. The &lt;em&gt;Aviator&lt;/em&gt;, the protagonist of this journey, will have to be instructed through code, to overcome the levels of each world.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FPaol-imi%2Fthe-aviator%2Fblob%2Fmaster%2Fimages%2Fscreens%2Fgame.gif%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FPaol-imi%2Fthe-aviator%2Fblob%2Fmaster%2Fimages%2Fscreens%2Fgame.gif%3Fraw%3Dtrue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As with any journey, the difficulty grows over time. Starting from the first simple challenges, the game ends with a last &lt;em&gt;"impossible"&lt;/em&gt; level, which represents that stage to reach to mark the beginning of a new part of the journey.&lt;/p&gt;

&lt;p&gt;Do you think you can reach it? Well, if you like challenges, what are you waiting for? Test yourself and challenge friends and colleagues 😎&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://paol-imi.github.io/the-aviator/" rel="noopener noreferrer"&gt;&lt;strong&gt;Online Game&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://paol-imi.github.io/the-aviator/tutorial/#/" rel="noopener noreferrer"&gt;&lt;strong&gt;Tutorial&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The game is also available on Github.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/paol-imi" rel="noopener noreferrer"&gt;
        paol-imi
      &lt;/a&gt; / &lt;a href="https://github.com/paol-imi/the-aviator" rel="noopener noreferrer"&gt;
        the-aviator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🎮 Welcome to the Aviator game!
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;em&gt;As a computer engineering student and creator of this project, I would recommend tools like this as educational support👨‍🎓 in schools and universities. With targeted design choices and an advanced code debugging system (with time travel), The Game tries to provide the best developer experience and guide the student's reasoning in each challenge.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Special thanks
&lt;/h2&gt;

&lt;p&gt;The inspiration for the protagonist of the game came to me thanks to &lt;a href="https://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/" rel="noopener noreferrer"&gt;this&lt;/a&gt; fantastic project, from which I took the name and the sprite of the Aviator.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>⚛️ Reparenting is now possible with React</title>
      <dc:creator>Paolo Longo</dc:creator>
      <pubDate>Sat, 23 May 2020 17:00:04 +0000</pubDate>
      <link>https://forem.com/paolimi/reparenting-is-now-possible-with-react-3ci0</link>
      <guid>https://forem.com/paolimi/reparenting-is-now-possible-with-react-3ci0</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/@paolimi/reparenting-with-react-426d12fb6d0d" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I am designing an app similar to &lt;a href="https://trello.com/" rel="noopener noreferrer"&gt;Trello&lt;/a&gt;. On the main page, I want some vertical Lists and some Cards that can be dragged from one List to another.&lt;/p&gt;

&lt;p&gt;How can I transfer a Card component after dragging? With React it seems quite easy. To change the Parent component of a Child component, the components have to be &lt;strong&gt;re-rendered&lt;/strong&gt; with that Child in its new Parent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzycgtacuys3edzhy3c1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzycgtacuys3edzhy3c1h.png" alt="Re-render"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the same way, I can transfer a &lt;code&gt;&amp;lt;Card&amp;gt;&lt;/code&gt; into a new &lt;code&gt;&amp;lt;List&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I implement a first draft of the code and try it, I take a Card with the mouse and drag it between the various Lists. The transfer takes place, but, unfortunately, the Card component is unmounted, re-mounted, and &lt;strong&gt;loses its internal state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Moreover the feedback from the drag animation isn't so positive. When I perform several drags quickly in succession, the App slows down and for a few moments there is a considerable &lt;strong&gt;loss of frames&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In fact, the DOM elements of the Card are recreated from scratch and this is having a negative impact on &lt;strong&gt;performance&lt;/strong&gt;. Also, one of the elements is a scrollable &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that loses its scroll position, I guess other elements such as &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; can have similar problems.&lt;/p&gt;

&lt;p&gt;With some effort, I can redesign the App to use Card components without a local state, but in any case I cannot avoid that the DOM elements are recreated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it possible to prevent the component from being re-mounted?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Well, if you are reading this article it is likely that the answer is positive :), but when I asked myself the question for the first time I did not find a definitive answer, probably because it was not there yet. Let's continue with the story.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I start looking for an answer in the React repository on Github, maybe there is something useful in the issues section. I find there is a term for what I'm looking for, and it's &lt;strong&gt;Reparenting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Reparenting aims to improve both the Developer and the User Experience."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some open &lt;a href="https://github.com/facebook/react/issues/3965" rel="noopener noreferrer"&gt;issues&lt;/a&gt; confirm that React does not yet provide specific APIs to handle it, my hopes that something like &lt;code&gt;React.transferComponent( )&lt;/code&gt; exists quickly fade away.&lt;/p&gt;

&lt;p&gt;An approach I discover is &lt;code&gt;ReactDOM.unstable_renderSubtreeIntoContainer( )&lt;/code&gt;, the name looks cool but the &lt;code&gt;unstable&lt;/code&gt; tag and the fact that this API has been deprecated are enough to make me look for something else. Searches continue on Medium, Dev, and other platforms, the only possible solution seems to be the use of the &lt;a href="https://reactjs.org/docs/portals.html" rel="noopener noreferrer"&gt;Portals&lt;/a&gt;. A Tweet by Dan Abramov definitely convinces me to try them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4eqmom3pyo900kod2gy8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4eqmom3pyo900kod2gy8.png" alt="Tweet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The portals approach
&lt;/h1&gt;

&lt;p&gt;I open the React documentation in the Portals section. I start reading the guide and doing some tests to get familiar with these APIs.&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;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&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;PortalComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;children&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;return&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createPortal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&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;I know that I cannot move a component elsewhere in the App or it will be re-mounted, so every Child component must be part of the &lt;strong&gt;same Parent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Should I use a portal for each Child? That way I could decide in which container element to render each of them. But how do I create containers? Do I have to write something like &lt;code&gt;document.createElement('div')&lt;/code&gt; 🤨? I could instead use ref to other components. Where do I render those components? Refs are empty initially, should I force a second render? I wanted each Parent to provide a different Context, How can I do that if I am forced to use only one Parent?…&lt;/p&gt;

&lt;p&gt;What a mess, the more I try to implement it, the more forced the approach seems to me. It doesn't give me the feeling of being very &lt;strong&gt;"reactive"&lt;/strong&gt;, probably because portals have been designed for other purposes:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component." - React docs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This process is more related to the DOM, at the &lt;strong&gt;"React level"&lt;/strong&gt; the Child is still part of the same Parent, not exactly what I am looking for.&lt;/p&gt;
&lt;h1&gt;
  
  
  The new solution
&lt;/h1&gt;

&lt;p&gt;Maybe I'm looking for a solution in the wrong place, it is possible that, if it exists, it is more internal to React than I think.&lt;/p&gt;

&lt;p&gt;What I know is that React represents my App with a &lt;strong&gt;tree of instances&lt;/strong&gt;, where each instance corresponds to a component. When re-rendering a part of the App, its sub-tree is recreated and compared with the old one, so as to find the changes that have been made and update the DOM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe03gd8j1agsoxhdzys8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe03gd8j1agsoxhdzys8v.png" alt="ReactTree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Due to the way this comparison is implemented, there is no way to make React &lt;strong&gt;aware of the transfer&lt;/strong&gt; of a component. Indeed, If I try to re-render a Card component somewhere else, the result will be the unmounting of the component and the mounting of a new one.&lt;/p&gt;

&lt;p&gt;How can I change this behavior? I could try to &lt;strong&gt;interact with the internal tree&lt;/strong&gt;, find the instance of the Card that I want to transfer, and insert it in the new List. In this way, after a &lt;strong&gt;re-rendering&lt;/strong&gt;, both the old and the new tree would have the transferred Card in the same place and the comparison would not cause the re-mount of the component, It might work!&lt;/p&gt;

&lt;p&gt;Before starting to design a solution, to avoid running into dead ends I impose some &lt;strong&gt;constraints&lt;/strong&gt; that the final result must respect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;It must not rely on any unstable method&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Reparenting must be able to work without redesigning the App&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;It must respect the philosophy and patterns of React&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have a solid starting point, now I have to understand how these react internals are actually &lt;strong&gt;implemented&lt;/strong&gt;. I find out that starting from version 16, React rolled out a new implementation of that internal instances tree named &lt;strong&gt;Fiber&lt;/strong&gt;. I read some articles about it to get a more complete picture, and when I think I have a fairly &lt;strong&gt;broad view&lt;/strong&gt; on the topic, I start to browse the React source code in search of a solution.&lt;/p&gt;

&lt;p&gt;After several days of testing and research, I finally have a first draft of code to try, inside a file named &lt;code&gt;react-reparenting.js&lt;/code&gt;. I import it into my App, add a few lines of code, and… It &lt;strong&gt;works!&lt;/strong&gt; The Card is not re-mounted and the goals that I have set for myself have all been respected.&lt;/p&gt;

&lt;p&gt;This story can finally have a nice ending, I can continue the development of my App. Maybe, for the next obstacle that I will face, I will find a story like this to read.&lt;/p&gt;
&lt;h1&gt;
  
  
  The end of the story
&lt;/h1&gt;

&lt;p&gt;This story ends with the publication of the package on &lt;a href="https://github.com/paol-imi/react-reparenting" rel="noopener noreferrer"&gt;Github&lt;/a&gt; and with the writing of this article. Before presenting it, I want to share with you what my vision is at the end of this project.&lt;br&gt;
 &lt;br&gt;
I strongly believe that &lt;strong&gt;Reparenting&lt;/strong&gt; is not only a way of managing these situations, but &lt;strong&gt;The way&lt;/strong&gt;, and I also believe that in the future React will implement it natively.&lt;/p&gt;

&lt;p&gt;In my opinion, the reason why this feature has not yet been implemented is that the cases in which it is really necessary are not many. Often the elements to be transferred are stateless and very simple, so it is an &lt;strong&gt;acceptable compromise&lt;/strong&gt; to re-mount them since the difference in performance is almost zero, and there is no state or lifecycle to be interrupted.&lt;/p&gt;

&lt;p&gt;I'm not saying that React will implement Reparenting as it has been implemented here, or that the APIs that will be provided will be similar to these, but  I hope this package, thanks also to its simplicity, can lay the foundations for the use and diffusion of Reparenting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Unmounting one component and mounting another identical one is just a simple compromise that works in most cases. The component should always be transferred, without its lifecycle being interrupted."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwepdeu1ecqxua4v6vggh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwepdeu1ecqxua4v6vggh.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0gwgvd9557j7w9saa41d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0gwgvd9557j7w9saa41d.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the package on &lt;a href="https://github.com/paol-imi/react-reparenting" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. On the GitHub page you will also find the documentation and links to various examples on Codesandbox.&lt;br&gt;
Now let's see a simple implementation.&lt;/p&gt;

&lt;p&gt;First, let's define the &lt;code&gt;&amp;lt;Child&amp;gt;&lt;/code&gt; component, we will use a very simple one.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Now we can use the &lt;code&gt;&amp;lt;Reparentable&amp;gt;&lt;/code&gt; component, it has to be the direct parent of the children to reparent. Each &lt;code&gt;&amp;lt;Reparentable&amp;gt;&lt;/code&gt; must have a unique id.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now we can reparent a &lt;code&gt;&amp;lt;Child&amp;gt;&lt;/code&gt;. First we have to send its fibers using the &lt;code&gt;sendReparentableChild( )&lt;/code&gt; method, then we just have to re-render the App. The transferred component will not be re-mounted.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;That's all. It is also possible to create a custom Parent component and use the &lt;code&gt;&amp;lt;Reparentable&amp;gt;&lt;/code&gt; inside it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Special thanks
&lt;/h1&gt;

&lt;p&gt;During the development of this project, I thought that I would lose my mind managing every use case &lt;em&gt;(context, memo, some edge cases with fibers…)&lt;/em&gt;. With pleasant surprise React worked in each of these cases without modification, a sign of the amazing work that the &lt;strong&gt;React Team&lt;/strong&gt; has done over the years.&lt;/p&gt;

&lt;p&gt;I want also to thank the &lt;strong&gt;authors&lt;/strong&gt; of these amazing articles, without them the work would have been longer and more tedious.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/acdlite/react-fiber-architecture" rel="noopener noreferrer"&gt;React fiber architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/deep-dive-into-react-fiber-internals" rel="noopener noreferrer"&gt;Deep dive into react fiber internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e" rel="noopener noreferrer"&gt;An in-depth overview of the new reconciliation algorithm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
