<?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: Hodeem</title>
    <description>The latest articles on Forem by Hodeem (@hmcodes).</description>
    <link>https://forem.com/hmcodes</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%2F648963%2F8cb15da6-9d65-4e61-8920-fdcb908cf3ae.png</url>
      <title>Forem: Hodeem</title>
      <link>https://forem.com/hmcodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hmcodes"/>
    <language>en</language>
    <item>
      <title>Under the hood: React</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Fri, 12 Dec 2025 13:44:36 +0000</pubDate>
      <link>https://forem.com/hmcodes/under-the-hood-react-3gbd</link>
      <guid>https://forem.com/hmcodes/under-the-hood-react-3gbd</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I've wanted to do this since the moment I started using React: understand what makes it tick. This is not a granular review of the source code. Instead, this is an overview of some of the key packages and integrations inside React. Doing this research helped me reason about React better and debug issues more confidently. Hopefully you'll gain a better perspective too.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Layers
&lt;/h1&gt;

&lt;p&gt;React, I discovered, isn't very useful as a standalone package. It functions as an API layer and delegates heavily to the &lt;code&gt;react-reconciler&lt;/code&gt; package. That's why it's often paired with a renderer such as &lt;code&gt;react-dom&lt;/code&gt; which is bundled with &lt;code&gt;react-reconciler&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;So, to learn about React, we have to learn about &lt;code&gt;react-reconciler&lt;/code&gt; and its key dependency, the &lt;code&gt;scheduler&lt;/code&gt; package. Let's start with &lt;code&gt;scheduler&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  scheduler
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;scheduler&lt;/code&gt; package enables React's concurrent features by breaking work into small chunks and managing the execution priority. Why is this important?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"With synchronous rendering, once an update starts rendering, nothing can interrupt it until the user can see the result on screen."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React v18.0 | March 29, 2022 by The React Team&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before concurrent React, updates were synchronous, which means they blocked the main thread until they were complete. This resulted in unresponsive UIs and janky animations. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;scheduler&lt;/code&gt; solves this by implementing "cooperative scheduling". In other words, tasks voluntarily yield control back to the host so that it can use the main thread for other tasks. This means &lt;code&gt;scheduler&lt;/code&gt; does work for a short interval (~5ms), checks if it's time to yield, voluntarily yields control if the deadline has passed, and waits until it gets another turn to pick back up where it left off. &lt;/p&gt;

&lt;p&gt;Cooperative scheduling is managed by the "Message Loop" and the actual work is managed by the "Work Loop".&lt;/p&gt;

&lt;h2&gt;
  
  
  Tasks, two loops, and two queues
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;unstable_scheduleCallback&lt;/code&gt; function, I'll call it &lt;code&gt;scheduleCallback&lt;/code&gt; to keep it simple, is the main means of scheduling concurrent (non-sync) work.&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="nf"&gt;unstable_scheduleCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;priorityLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PriorityLevel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;},&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;Work in the &lt;code&gt;scheduler&lt;/code&gt; is stored in a Task object:&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;export&lt;/span&gt; &lt;span class="nx"&gt;opaque&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Callback&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="na"&gt;priorityLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PriorityLevel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;expirationTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sortIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isQueued&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;callback&lt;/code&gt; is the actual work to be done. It can be cancelled by setting this field to null. The &lt;code&gt;priorityLevel&lt;/code&gt; is one of the &lt;code&gt;scheduler&lt;/code&gt;'s priority levels.&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;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PriorityLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NoPriority&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ImmediatePriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserBlockingPriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NormalPriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LowPriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IdlePriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;scheduler&lt;/code&gt; uses these priority levels to manage execution priority. &lt;/p&gt;

&lt;p&gt;To understand the next three fields &lt;code&gt;startTime&lt;/code&gt;, &lt;code&gt;expirationTime&lt;/code&gt; and &lt;code&gt;sortIndex&lt;/code&gt; we need to first talk about the two queues in the &lt;code&gt;scheduler&lt;/code&gt; - the Task queue and the Timer queue. These are both priority queues, implemented by using a min heap. In other words, in these priority queues the smallest values are at the front (have the highest priority) and are dequeued first.  &lt;/p&gt;

&lt;p&gt;The Task queue is used to store tasks that are ready to execute, and the Timer queue is used to store those that aren't. When tasks are created, they are assigned a &lt;code&gt;startTime&lt;/code&gt; which indicates when they are eligible for execution and an &lt;code&gt;expirationTime&lt;/code&gt; which indicates when they must be executed by. If the &lt;code&gt;startTime&lt;/code&gt; is greater than &lt;code&gt;currentTime&lt;/code&gt;, then the task is added to the Timer queue, or else it's added to the Task queue. The Task is pushed to the relevant queue in the &lt;code&gt;scheduleCallback&lt;/code&gt; function.&lt;br&gt;
Here's how the &lt;code&gt;startTime&lt;/code&gt; is calculated:&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;Immediate&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="c1"&gt;// available now&lt;/span&gt;
&lt;span class="nx"&gt;Delayed&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="c1"&gt;// available in the future&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;expirationTime&lt;/code&gt; creates a grace period that controls how long the &lt;code&gt;scheduler&lt;/code&gt; is willing to yield before a Task becomes so urgent that it must be executed without interruption. To calculate the expiration time, we add a timeout to the &lt;code&gt;startTime&lt;/code&gt;, and the value of the timeout depends on the PriorityLevel. The timeout value ranges from -1ms for &lt;code&gt;ImmediatePriority&lt;/code&gt; to approx. 10,000ms for &lt;code&gt;LowPriority&lt;/code&gt;. So,&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;expirationTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tasks are sorted by the &lt;code&gt;startTime&lt;/code&gt; in the Timer queue, and by the &lt;code&gt;expirationTime&lt;/code&gt; in the Task queue. Therefore, the &lt;code&gt;sortIndex&lt;/code&gt; is equal to the &lt;code&gt;startTime&lt;/code&gt; for tasks in the Timer queue, and the &lt;code&gt;expirationTime&lt;/code&gt; for those in the Task queue. &lt;/p&gt;

&lt;p&gt;Here are some examples of triggers for different priority levels:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Priority Level&lt;/th&gt;
&lt;th&gt;Trigger examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;ImmediatePriority&lt;/code&gt; (Sync)&lt;/td&gt;
&lt;td&gt;Rarely used in modern React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UserBlockingPriority&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;onScroll&lt;/code&gt;, &lt;code&gt;onDrag&lt;/code&gt;, &lt;code&gt;onMouseMove&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NormalPriority&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;startTransition()&lt;/code&gt;, &lt;code&gt;useDeferredValue&lt;/code&gt; (default for most &lt;code&gt;scheduler&lt;/code&gt; work)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IdlePriority&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Offscreen/hidden content rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Synchronous work skips the scheduling and is queued using the &lt;code&gt;queueMicrotask&lt;/code&gt; API.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Work Loop
&lt;/h3&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="nf"&gt;workLoop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;advanceTimers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;currentTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskQueue&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="nx"&gt;currentTask&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;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;enableAlwaysYieldScheduler&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;currentTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expirationTime&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;shouldYieldToHost&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This currentTask hasn't expired, and we've reached the deadline.&lt;/span&gt;
        &lt;span class="k"&gt;break&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;// ... execute callback ...&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 Work Loop's primary function is to dequeue Tasks from the Task queue and execute their callbacks until it's time to yield control to the host. The Work Loop also updates the two queues via &lt;code&gt;advanceTimers&lt;/code&gt;. Tasks in the Timer queue whose &lt;code&gt;startTime&lt;/code&gt; has passed (&lt;code&gt;startTime&lt;/code&gt; &amp;lt;= &lt;code&gt;currentTime&lt;/code&gt;) are promoted to the Task queue. &lt;/p&gt;

&lt;p&gt;Long-running or incomplete Tasks' existing &lt;code&gt;callback&lt;/code&gt; is replaced with a "continuation callback", which allows the &lt;code&gt;scheduler&lt;/code&gt; to pick up where it left off on the next run. Cancelled tasks are simply discarded when dequeued. The loop repeatedly checks &lt;code&gt;shouldYieldToHost&lt;/code&gt; to decide if it should continue working or stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Message Loop
&lt;/h3&gt;

&lt;p&gt;You may be wondering, "So when the Work Loop exits, what mechanism restarts it?". That's where the Message Loop comes in. React prefers to use the non-standard &lt;code&gt;setImmediate&lt;/code&gt; API, but if the environment doesn't support it then it falls back to the Channel Messaging API or &lt;code&gt;setTimeout&lt;/code&gt; for non-browser environments. &lt;/p&gt;

&lt;p&gt;This is one of the clever parts of React - a bit cheeky if you ask me. The Channel Messaging API was designed for cross-context communication, but React keeps both ports and uses them for a scheduling trick. Here's how:&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;channel&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;MessageChannel&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performWorkUntilDeadline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;schedulePerformWorkUntilDeadline&lt;/span&gt; &lt;span class="o"&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="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;performWorkUntilDeadline&lt;/code&gt; is the function that ultimately starts the Work Loop and when the Work Loop is ready to yield to the host, another message is posted by invoking &lt;code&gt;schedulePerformWorkUntilDeadline()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This ensures that when the message is processed by the host, the &lt;code&gt;onmessage&lt;/code&gt; callback fires and the Work Loop picks up where it left off. Why this API? By using the Channel Messaging API, React avoids the 4ms minimum delay associated with an alternative like &lt;code&gt;setTimeout&lt;/code&gt;. Tecnologia!&lt;/p&gt;

&lt;h2&gt;
  
  
  react-reconciler
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;react-reconciler&lt;/code&gt; package determines what changes need to be made to the UI and leverages &lt;code&gt;scheduler&lt;/code&gt; to get the work done. It is based on the Fiber Architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fiber Architecture
&lt;/h3&gt;

&lt;p&gt;A Fiber is a JavaScript object representing a unit of work - it contains everything React needs to process that component. Here's a simplified Fiber type:&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;type&lt;/span&gt; &lt;span class="nx"&gt;Fiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Identity&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WorkTag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Component type (Function, Class, Host, etc.)&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;// The actual component (function, class, 'div')&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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="c1"&gt;// For reconciliation&lt;/span&gt;

  &lt;span class="c1"&gt;// Tree structure&lt;/span&gt;
  &lt;span class="na"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&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="c1"&gt;// Parent&lt;/span&gt;
  &lt;span class="na"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&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="c1"&gt;// First child&lt;/span&gt;
  &lt;span class="na"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&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="c1"&gt;// Next sibling&lt;/span&gt;

  &lt;span class="c1"&gt;// Effects&lt;/span&gt;
  &lt;span class="na"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// What work this fiber needs (Placement, Update, etc.)&lt;/span&gt;
  &lt;span class="na"&gt;subtreeFlags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// What work children need (bubbled up)&lt;/span&gt;

  &lt;span class="c1"&gt;// Scheduling&lt;/span&gt;
  &lt;span class="na"&gt;lanes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Priority of pending work&lt;/span&gt;
  &lt;span class="na"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// Priority of children's work&lt;/span&gt;

  &lt;span class="c1"&gt;// Double buffering&lt;/span&gt;
  &lt;span class="na"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&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="c1"&gt;// The other version of this fiber&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flags mark what work needs to be done on a fiber during commit. They're bitmasks combined with | and checked with &amp;amp;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Common flags&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NoFlags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;        &lt;span class="mb"&gt;0b0000000000000000000000000000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Placement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;      &lt;span class="mb"&gt;0b0000000000000000000000000000010&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Needs DOM insertion&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;         &lt;span class="mb"&gt;0b0000000000000000000000000000100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Needs DOM update&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ChildDeletion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="mb"&gt;0b0000000000000000000000000010000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Has children to remove&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;            &lt;span class="mb"&gt;0b0000000000000000000001000000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Ref needs attaching&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Passive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;        &lt;span class="mb"&gt;0b0000000000000000000100000000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Has useEffect&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;       &lt;span class="mb"&gt;0b0000000000000000000010000000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// getSnapshotBeforeUpdate&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;       &lt;span class="mb"&gt;0b0000000000000000000000001000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Has setState callback&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an example of how flags are used to determine if there's work to be done:&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;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;NoFlags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This fiber has an Update effect&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;finishedWork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateQueue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ... run update effects&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lanes represent priority levels for updates. Higher priority means lower bit position. Each update gets assigned a lane and React processes higher-priority lanes first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Priority order (highest to lowest)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SyncLane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;              &lt;span class="mb"&gt;0b0000000000000000000000000000010&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Urgent (click, input)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;InputContinuousLane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;   &lt;span class="mb"&gt;0b0000000000000000000000000001000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Drag, scroll&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DefaultLane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;           &lt;span class="mb"&gt;0b0000000000000000000000000100000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Normal updates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These lanes are mapped to priorities from the &lt;code&gt;scheduler&lt;/code&gt; before calling the &lt;code&gt;scheduleCallback&lt;/code&gt; function.&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;schedulerPriorityLevel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lanesToEventPriority&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextLanes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Scheduler does have an "ImmediatePriority", but now that we use&lt;/span&gt;
      &lt;span class="c1"&gt;// microtasks for sync work we no longer use that. Any sync work that&lt;/span&gt;
      &lt;span class="c1"&gt;// reaches this path is meant to be time sliced.&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;DiscreteEventPriority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;ContinuousEventPriority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;schedulerPriorityLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UserBlockingSchedulerPriority&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;DefaultEventPriority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;schedulerPriorityLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NormalSchedulerPriority&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;IdleEventPriority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;schedulerPriorityLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IdleSchedulerPriority&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;schedulerPriorityLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NormalSchedulerPriority&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;break&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;newCallbackNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scheduleCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;schedulerPriorityLevel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;performWorkOnRootViaSchedulerTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;root&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;Here's an example of how lanes are used to check if a fiber has pending work:&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;includesSomeLane&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="nx"&gt;Lanes&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="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;NoLanes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ← BITMASK AND&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkScheduledUpdateOrContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;updateLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lanes&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="nf"&gt;includesSomeLane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Has work in these lanes&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;Fibers are stored in two trees, the Current tree and the Work-in-Progress (WIP) tree. The Current tree represents the UI that's currently  visible to the user, while the WIP tree represents the next state of the UI that's being built. &lt;/p&gt;

&lt;p&gt;Each fiber has an &lt;code&gt;alternate&lt;/code&gt; property that links corresponding fibers between trees. After all the changes have been committed, the trees swap roles. So, the WIP tree becomes Current and the Current becomes the new WIP. This "double buffering" pattern allows React to quickly swap to the new UI atomically and build the next UI without affecting the current one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reconciliation
&lt;/h3&gt;

&lt;p&gt;The reconciliation in &lt;code&gt;react-reconciler&lt;/code&gt; is split into two phases: the render phase and the commit phase. &lt;/p&gt;

&lt;h4&gt;
  
  
  The render phase
&lt;/h4&gt;

&lt;p&gt;The render phase is where React traverses the fiber tree, calls your component functions, and determines what changed. This phase is interruptible, meaning that React can pause work to let the host handle user input, then resume later. &lt;/p&gt;

&lt;p&gt;For concurrent updates &lt;code&gt;react-reconciler&lt;/code&gt; schedules work using &lt;code&gt;scheduler&lt;/code&gt;'s &lt;code&gt;scheduleCallback&lt;/code&gt; function that was shown earlier.&lt;/p&gt;

&lt;p&gt;When this callback is eventually processed by the &lt;code&gt;scheduler&lt;/code&gt;'s work loop,  it indirectly starts another work loop in the &lt;code&gt;react-reconciler&lt;/code&gt;. This second loop in the &lt;code&gt;react-reconciler&lt;/code&gt; traverses the fiber tree and processes each fiber. &lt;/p&gt;

&lt;p&gt;The function responsible for this second work loop is &lt;code&gt;workLoopConcurrentByScheduler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;workLoopConcurrentByScheduler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Perform work until Scheduler asks us to yield&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workInProgress&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;shouldYield&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workInProgress&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;This second work loop processes one fiber at a time. After each unit of work, the loop checks if it's time to yield or if there's no more work. If either condition is true, React yields back to the host and the &lt;code&gt;scheduler&lt;/code&gt; can resume later. Note: &lt;code&gt;shouldYield&lt;/code&gt; is the &lt;code&gt;shouldYieldToHost&lt;/code&gt; function exported from the &lt;code&gt;scheduler&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If this is feeling a bit loopy, don't worry - it took me a while to get a hang of it. To summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;scheduler&lt;/code&gt;'s Work Loop mainly processes Tasks and is interruptible between Tasks.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;scheduler&lt;/code&gt;'s Message Loop exists to ensure that the Work Loop is re-entered if there are outstanding Tasks.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;react-reconciler&lt;/code&gt;'s Work Loop traverses the Fiber tree, processes Fibers and is interruptible between Fibers.&lt;/li&gt;
&lt;li&gt;Multiple Fibers can be processed within a single Task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;performUnitOfWork&lt;/code&gt; is the core of rendering. Each fiber passed to it goes through two functions, &lt;code&gt;beginWork&lt;/code&gt; and &lt;code&gt;completeWork&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Phase 1: "Begin" - process this fiber, return its first child&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entangledRenderLanes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Other code&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;next&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="c1"&gt;// No children - complete this fiber and move to sibling/parent&lt;/span&gt;
    &lt;span class="nf"&gt;completeUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Has children - process the first child next&lt;/span&gt;
    &lt;span class="nx"&gt;workInProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traversal of the fiber-tree is depth-first, and &lt;code&gt;beginWork&lt;/code&gt; is called for each fiber as we descend. &lt;code&gt;beginWork&lt;/code&gt; does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks if the fiber has pending work in the current lanes (&lt;code&gt;fiber.lanes&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Calls your component function (for function components) or &lt;code&gt;render()&lt;/code&gt; (for class components)&lt;/li&gt;
&lt;li&gt;Reconciles children by diffing old vs new to decide what changed&lt;/li&gt;
&lt;li&gt;Sets flags on fibers that need DOM work&lt;/li&gt;
&lt;li&gt;Returns the first child fiber (or null if no children)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;completeUnitOfWork&lt;/code&gt; function is called when we're going back up.&lt;br&gt;
When a fiber has no children (or all children are processed), the &lt;code&gt;react-reconciler&lt;/code&gt; "completes" it. This means that the function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates actual DOM nodes (for host components like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Bubbles child flags up to &lt;code&gt;subtreeFlags&lt;/code&gt; so the commit phase knows which subtrees have work.
&lt;/li&gt;
&lt;/ul&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="nf"&gt;completeUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;completedWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unitOfWork&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;completedWork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&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;returnFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;completedWork&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="c1"&gt;// Create/update DOM nodes, bubble up flags&lt;/span&gt;
    &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completedWork&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entangledRenderLanes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Move to sibling, or back up to parent&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;siblingFiber&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;workInProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;siblingFiber&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;completedWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;returnFiber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;workInProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;completedWork&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="nx"&gt;completedWork&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here's an example of how the &lt;code&gt;react-reconciler&lt;/code&gt; walks the tree depth-first:&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;App&lt;/span&gt;
    &lt;span class="o"&gt;/&lt;/span&gt;   &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="nx"&gt;Header&lt;/span&gt;  &lt;span class="nx"&gt;Main&lt;/span&gt;
  &lt;span class="o"&gt;/&lt;/span&gt;         &lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="nx"&gt;Logo&lt;/span&gt;      &lt;span class="nx"&gt;Article&lt;/span&gt;

&lt;span class="nx"&gt;Traversal&lt;/span&gt; &lt;span class="nx"&gt;order&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="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="nx"&gt;Logo&lt;/span&gt;  
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Logo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Logo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;move&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nf"&gt;sibling &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;none&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;move&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;sibling&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="nx"&gt;Article&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;completeWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every fiber needs processing on every render. The &lt;code&gt;entangledRenderLanes&lt;/code&gt; variable tracks which priority levels we're currently processing. In &lt;code&gt;beginWork&lt;/code&gt;, React checks:&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;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lanes&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;NoLanes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This fiber has no pending work at the current priority&lt;/span&gt;
  &lt;span class="c1"&gt;// Bail out - reuse the existing fiber&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bailoutOnAlreadyFinishedWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;workInProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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 lets React skip entire subtrees that don't have updates at the current priority.&lt;/p&gt;

&lt;p&gt;When the work loop finishes (all fibers processed), the WIP tree is complete and then the &lt;code&gt;react-reconciler&lt;/code&gt; moves to the commit phase to apply these changes to the actual DOM.&lt;/p&gt;

&lt;h4&gt;
  
  
  The commit phase
&lt;/h4&gt;

&lt;p&gt;The commit phase is actually divided into 3 synchronous sub-phases. They are the Before Mutation, Mutation, and Layout phases. &lt;/p&gt;

&lt;p&gt;The Before Mutation phase captures any DOM state that might change (like scroll positions) before React modifies anything. Note: This is when &lt;code&gt;getSnapshotBeforeUpdate&lt;/code&gt; runs.&lt;/p&gt;

&lt;p&gt;The "Mutation" phase is where the DOM is actually modified. Operations such as inserting new nodes, updating attributes/text, and removing deleted nodes take place in this phase. The &lt;code&gt;react-reconciler&lt;/code&gt; processes all fibers with &lt;code&gt;Placement&lt;/code&gt;, &lt;code&gt;Update&lt;/code&gt;, or &lt;code&gt;ChildDeletion&lt;/code&gt; flags. This is the phase when the user-visible changes happen.&lt;/p&gt;

&lt;p&gt;The tree swap (when the WIP tree becomes the new Current tree) takes place between the Mutation and Layout phases.&lt;/p&gt;

&lt;p&gt;The Layout phase serves to run effects that need to read the freshly-updated DOM synchronously. This includes running the &lt;code&gt;useLayoutEffect&lt;/code&gt; hooks, attaching refs, and class lifecycle methods like &lt;code&gt;componentDidMount&lt;/code&gt;/&lt;code&gt;componentDidUpdate&lt;/code&gt;. These run before the host paints, so you can measure the DOM or make synchronous adjustments.&lt;/p&gt;

&lt;p&gt;There's also a fourth phase that happens asynchronously after paint:&lt;br&gt;
the Passive Effects phase which runs &lt;code&gt;useEffect&lt;/code&gt; callbacks. These are intentionally delayed so they don't block the host from painting the updated UI to screen.&lt;/p&gt;
&lt;h3&gt;
  
  
  HostConfig
&lt;/h3&gt;

&lt;p&gt;By now you may have noticed that these methods and terms are a bit abstract. That's by design. Remember that the &lt;code&gt;react-reconciler&lt;/code&gt; is primarily concerned with managing the Fiber trees and is flexible enough to be used in different environments. This is facilitated by a conceptual interface called &lt;code&gt;HostConfig&lt;/code&gt; that allows different renderers to give &lt;code&gt;react-reconciler&lt;/code&gt; instructions on how to manage the specific host platform. &lt;/p&gt;

&lt;p&gt;I say conceptual because you won't find an interface called &lt;code&gt;HostConfig&lt;/code&gt; in the source code; however, there are certain fields and methods that the &lt;code&gt;react-reconciler&lt;/code&gt; expects to import. Here's a simplified snippet of the HostConfig 'interface':&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;HostConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// e.g. DOM renderer returns a DOM node&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="na"&gt;supportsMutation&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="c1"&gt;// it works by mutating nodes&lt;/span&gt;
  &lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// e.g. DOM renderer would call .appendChild() here&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&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;react-reconciler&lt;/code&gt; expects to import these properties from the &lt;code&gt;ReactFiberConfig&lt;/code&gt; file. 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      
  &lt;span class="nx"&gt;createTextInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          
  &lt;span class="nx"&gt;resolveSingletonInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="c1"&gt;// more imports&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="s1"&gt;./ReactFiberConfig&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;However, if you check the contents of the &lt;code&gt;ReactFiberConfig.js&lt;/code&gt; file, here's what you'll find:&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;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="s1"&gt;This module must be shimmed by a specific renderer.&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;There are two classes of renderers, first-party renderers and third-party renderers and the way shimming is done depends on the class. First-party renderers are those found in the React monorepo, and third-party renderers are those that aren't. &lt;/p&gt;

&lt;p&gt;For first-party renderers, the shim is the correct fork of the ReactFiberConfig file identified at build-time by the bundler. For example, if you're bundling the &lt;code&gt;react-dom&lt;/code&gt; renderer, then the &lt;code&gt;ReactFiberConfig.dom.js&lt;/code&gt; fork will be selected. The fork has the implementation that satisfies the HostConfig 'interface'. &lt;/p&gt;

&lt;p&gt;For third-party renderers, you'll have to pass your HostConfig object to the instantiated Reconciler. It'll look 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;Reconciler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-reconciler&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;HostConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// You'll need to implement some methods here.&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;MyRenderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Reconciler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HostConfig&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;RendererPublicAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&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="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Call MyRenderer.updateContainer() to schedule changes on the roots.&lt;/span&gt;
    &lt;span class="c1"&gt;// See ReactDOM, React Native, or React ART for practical examples.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RendererPublicAPI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hooks
&lt;/h3&gt;

&lt;p&gt;Now, let's touch on hooks. If you've ever gone to the implementation of &lt;code&gt;useState&lt;/code&gt; you may have seen 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;function&lt;/span&gt; &lt;span class="nf"&gt;resolveDispatcher&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;dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactSharedInternals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H&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;dispatcher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&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;dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolveDispatcher&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;dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&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 first time I saw it, it was a real head-scratcher. One interesting thing that I discovered was that &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;react-reconciler&lt;/code&gt; are linked primarily by a shared mutable object called &lt;code&gt;ReactSharedInternals&lt;/code&gt;. &lt;code&gt;react&lt;/code&gt; exports the blank object, which looks 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;ReactSharedInternals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SharedStateClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;H&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// `H` is for hooks, that's all you need to know for now.&lt;/span&gt;
  &lt;span class="na"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;S&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;any&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;enableGestureTransition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ReactSharedInternals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;G&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and &lt;code&gt;react-reconciler&lt;/code&gt; imports the object indirectly, writes to it, and &lt;code&gt;react&lt;/code&gt; is able to read from the updated object. &lt;/p&gt;

&lt;p&gt;It gets even more interesting. &lt;code&gt;H&lt;/code&gt; will get assigned a Dispatcher, and the Dispatcher depends on the phase that React is currently in. For example, if it's in the mount phase then &lt;code&gt;ReactSharedInternals.H = HooksDispatcherOnMount&lt;/code&gt;. Or if it's in the update phase then &lt;code&gt;ReactSharedInternals.H = HooksDispatcherOnUpdate&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Each Dispatcher has phase-specific implementation for most of its properties:&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;HooksDispatcherOnMount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;readContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mountCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mountState&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;HooksDispatcherOnUpdate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;readContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updateCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updateState&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContextOnlyDispatcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;readContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;throwInvalidHookError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;throwInvalidHookError&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;The initial setup takes place when you call &lt;code&gt;root.render(&amp;lt;App /&amp;gt;)&lt;/code&gt; in your entry file, and the fields of &lt;code&gt;ReactSharedInternals&lt;/code&gt; are updated repeatedly at runtime. &lt;code&gt;ContextOnlyDispatcher&lt;/code&gt; is assigned to &lt;code&gt;ReactSharedInternals.H&lt;/code&gt; when React is outside of the render phase. So, if you've ever wondered where the 'Rule of Hooks' error was being thrown:&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="nf"&gt;throwInvalidHookError&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="s1"&gt;Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; one of the following reasons:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1. You might have mismatching versions of React and the renderer (such as React DOM)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2. You might be breaking the Rules of Hooks&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3. You might have more than one copy of React in the same app&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you know.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There are many more aspects of React that couldn't be covered in one article. Who knows? maybe I'll write about them someday. If you learned something new, please like and share this. And if you want me to do a deep dive on Hooks or some other React concept, leave a comment. Thanks for reading.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API" rel="noopener noreferrer"&gt;Channel Messaging API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/blog/2022/03/29/react-v18" rel="noopener noreferrer"&gt;React v18.0 | March 29, 2022 by The React Team&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Shuttering Sheltah</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Mon, 29 Sep 2025 00:59:47 +0000</pubDate>
      <link>https://forem.com/hmcodes/final-thoughts-a3h</link>
      <guid>https://forem.com/hmcodes/final-thoughts-a3h</guid>
      <description>&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I've decided to close the chapter on this part of my journey, and this piece is a documentation of my learnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  About
&lt;/h2&gt;

&lt;p&gt;Sheltah was intended to be a real estate platform that provided users with a great experience wherever they were in their journey. Some of the core features included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Granular search - users could sort and filter listings by price, number of bathrooms, parish, postal zone, etc. &lt;/li&gt;
&lt;li&gt;Tools and resources - like mortgage calculators and educational blog posts.&lt;/li&gt;
&lt;li&gt;Analytics - to help realtors better understand their followers and the performance of their listings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I got wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Having a weak value proposition&lt;/strong&gt;. The product was good, but not 10X better than current alternatives. It was simply not a big enough pull for users or for myself. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not starting small&lt;/strong&gt;. The overhead of setting up and maintaining native apps in both app stores was not the best use of time, especially in the early days. It would have been more efficient to start with a website, which would have allowed me to iterate and pivot faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Premature optimization&lt;/strong&gt;. Setting sail on the perfect ship doesn't matter if you're heading in the wrong direction. As a recovering perfectionist, it was &lt;em&gt;really&lt;/em&gt; hard to ship something that had bugs or wasn't pixel perfect. I should have focused on achieving the elusive PMF (Product-Market Fit) before dedicating time to ironing out wrinkles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not giving marketing the respect it deserves&lt;/strong&gt;. We all dream of building the "product that sells itself", but even those require a lil good ol' marketing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I gained
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Breadth&lt;/strong&gt;. Working on Sheltah just made me better across the entire stack, because I had to do everything myself. Design, engineering, marketing, you name it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Courage&lt;/strong&gt;. In the earliest days, I had to go for a walk before deploying the apps, just to ease my nerves. Lord have mercy, lol. Over time, that fear of failing on the big stage faded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perspective&lt;/strong&gt;. Engineering is difficult in its own right, but product and entrepreneurship are different beasts entirely. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I took a risk, and it didn't work out. I learned a lot though. Onwards. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Sheltah Stack (for the techies)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Project Management&lt;/td&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Design&lt;/td&gt;
&lt;td&gt;Figma, Excalidraw&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Front-end&lt;/td&gt;
&lt;td&gt;Expo (React Native), Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back-end&lt;/td&gt;
&lt;td&gt;Express, Node.js, Postman&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;Heroku, Netlify, AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Postgres&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analytics&lt;/td&gt;
&lt;td&gt;Sentry, Google Analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>learning</category>
      <category>product</category>
      <category>startup</category>
    </item>
    <item>
      <title>AI: What is RAG ?</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Sun, 25 Aug 2024 18:14:27 +0000</pubDate>
      <link>https://forem.com/hmcodes/ai-what-is-rag--k7o</link>
      <guid>https://forem.com/hmcodes/ai-what-is-rag--k7o</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As a software engineer working with AI and machine learning, you've likely encountered the term "RAG" or Retrieval-Augmented Generation. But what exactly is RAG, and why is it becoming increasingly important in AI systems? Let's dive into this exciting technology and explore its impact on the world of artificial intelligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RAG?
&lt;/h2&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG) is a technique that combines the power of large language models with the ability to access and incorporate external knowledge sources. &lt;/p&gt;

&lt;p&gt;In simple terms, RAG allows AI systems to "look up" information from a knowledge base before generating a response, much like how a human might consult a reference book or search the internet before answering a complex question.&lt;/p&gt;

&lt;p&gt;The core components of a RAG-enabled system typically include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A large language model (LLM)&lt;/li&gt;
&lt;li&gt;A knowledge base or external data source&lt;/li&gt;
&lt;li&gt;A retrieval mechanism to find relevant information&lt;/li&gt;
&lt;li&gt;An integration layer that combines retrieved information with the LLM's output&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How do RAG-enabled systems work?
&lt;/h2&gt;

&lt;p&gt;RAG has become an integral part of many advanced AI systems, particularly those dealing with natural language processing and generation. It bridges the gap between the vast but static knowledge encoded in pre-trained language models and the dynamic, up-to-date information available in external sources.&lt;/p&gt;

&lt;p&gt;In a typical RAG-enabled system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user input is processed to identify key topics or questions.&lt;/li&gt;
&lt;li&gt;The retrieval mechanism searches the knowledge base for relevant information.&lt;/li&gt;
&lt;li&gt;The retrieved information is provided as context to the language model.&lt;/li&gt;
&lt;li&gt;The language model generates a response based on both its pre-trained knowledge and the retrieved information.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process allows AI systems to provide more accurate, relevant, and up-to-date responses compared to relying solely on pre-trained models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of RAG
&lt;/h2&gt;

&lt;p&gt;Implementing RAG in AI systems offers several significant benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced knowledge retrieval&lt;/strong&gt;: RAG allows AI systems to access a vast array of external information, going beyond the limitations of their pre-trained knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced hallucinations&lt;/strong&gt;: By grounding responses in retrieved information, RAG helps minimize the problem of AI "hallucinations" or generating plausible-sounding but incorrect information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved contextual understanding&lt;/strong&gt;: The ability to retrieve relevant information helps AI systems better understand the context of user queries and provide more appropriate responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier updates&lt;/strong&gt;: With RAG, updating the system's knowledge is as simple as updating the external knowledge base, rather than retraining the entire model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better handling of specialized domains&lt;/strong&gt;: RAG excels in scenarios requiring domain-specific knowledge, as it can easily incorporate specialized databases or documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Retrieval-Augmented Generation represents a significant advancement in AI technology, offering a powerful way to enhance the capabilities of language models with external knowledge. As we've explored, RAG systems provide numerous benefits, including improved accuracy, flexibility, and the ability to handle specialized domains.&lt;/p&gt;

&lt;p&gt;As AI continues to evolve, we can expect RAG to play an increasingly important role in developing more intelligent, adaptable, and trustworthy systems. For software engineers working in AI and ML, understanding and implementing RAG techniques will likely become an essential skill in creating cutting-edge applications. So, I hope you'll have as much fun working with them as I will :)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AI: An overview of common LLM benchmarks</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Sun, 11 Aug 2024 22:57:20 +0000</pubDate>
      <link>https://forem.com/hmcodes/ai-an-overview-of-common-llm-benchmarks-3i7b</link>
      <guid>https://forem.com/hmcodes/ai-an-overview-of-common-llm-benchmarks-3i7b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;With almost every release of a state-of-the-art (SOTA) LLM, is an accompanying table (like the one below) that compares each of the frontrunners. &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%2Fvl7jvztf4ls07cnrbxwk.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%2Fvl7jvztf4ls07cnrbxwk.png" alt="Claude 3 benchmarks table" width="800" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're like me, most of the benchmarks seemed foreign, thereby making it difficult to understand what's going on. So, in this blog post I want to clarify the most common benchmarks. First, let's start by doing a quick summary of what LLMs and benchmarks are.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an LLM?
&lt;/h2&gt;

&lt;p&gt;A Large Language Model (LLM) is a type of machine learning model designed to understand and generate human language among other things. LLMs can also perform tasks such as answering questions, translating languages, summarizing texts, and even writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are benchmarks?
&lt;/h2&gt;

&lt;p&gt;A benchmark can be thought of as a standardized test to evaluate how well a model can complete specific tasks. The evaluation usually entails providing the model with tasks to complete, and once those tasks are completed, the model is given a score. The scale is dependent on the benchmark, so a higher score is not always better.&lt;/p&gt;

&lt;p&gt;With the summaries out of the way, let's review ten (10) common benchmarks:&lt;/p&gt;

&lt;h2&gt;
  
  
  AI2 Reasoning Challenge (ARC)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To measure a model's ability to correctly answer questions and demonstrate sound reasoning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: To correctly answer more than 7000 grade-school science questions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  HellaSwag (Harder Endings, Longer contexts and Low-shot Activities for Situations With Adversarial Generations)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To measure a model's ability to choose the most plausible ending for a given context, especially in scenarios where the context is longer, and the tasks are more challenging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is given a short story or context and must select the correct ending from a set of options. There are options that are tricky or misleading.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MMLU (Massive Multitask Language Understanding)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To assess a model's ability to understand and respond correctly across a wide range of subjects, from elementary knowledge to advanced topics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is tested with more than 15,000 questions from over 50 different subjects, including humanities, sciences, and social sciences, with questions designed to reflect varying levels of difficulty.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GSM8K (Grade School Math 8K)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To evaluate a model’s capability in solving grade-school-level math problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is presented with more than 8,000 grade-school math word problems and must solve them correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TruthfulQA
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To measure a model's ability to generate truthful and factually accurate responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is given more than 800 questions that could easily lead to incorrect or misleading answers, and it is evaluated on how truthful its responses are.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Winogrande
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To assess a model's understanding of common-sense reasoning and its ability to resolve ambiguous pronouns in sentences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is given sentences with ambiguous pronouns and must correctly identify which noun the pronoun refers to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Chatbot Arena
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To evaluate and compare the performance of different chatbots in open-ended conversations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: To engage in conversations with human evaluators who rate the chatbots based on various criteria.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  HumanEval
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To measure a model’s ability to write correct Python code to solve programming problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is given programming tasks, and its output is compared against expected solutions to determine correctness.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MBPP (Mostly Basic Programming Problems)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To evaluate a model's basic programming skills, focusing on the ability to solve simple coding problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is presented with a series of basic programming problems and is judged on the correctness and efficiency of its solutions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GLUE (General Language Understanding Evaluation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The goal&lt;/strong&gt;: To measure a model's ability to perform a variety of natural language understanding tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The test&lt;/strong&gt;: The model is tested on a suite of language tasks, including sentiment analysis, textual entailment, and sentence similarity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sentiment analysis&lt;/strong&gt; is the process of determining the emotional tone or opinion expressed in a piece of text, typically categorizing it as positive, negative, or neutral.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Textual entailment&lt;/strong&gt; is the task of determining whether a given piece of text (the hypothesis) can be inferred or logically follows from another piece of text (the premise).&lt;/p&gt;

&lt;p&gt;Here's an example of textual entailment:&lt;/p&gt;

&lt;p&gt;Premise: "The cat is on the mat."&lt;br&gt;
Hypothesis: "There is a cat."&lt;/p&gt;

&lt;p&gt;This is a positive textual entailment because the second sentence (hypothesis) can be inferred from the first sentence (premise).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Let's talk about shots
&lt;/h3&gt;

&lt;p&gt;Some benchmark diagrams may have terms like "0-shot CoT" or "5-shot" all over. Let's clarify these by tackling CoT first. &lt;/p&gt;

&lt;p&gt;Chain of Thought (CoT) is a technique used in language models where the model is encouraged to generate a series of intermediate reasoning steps before arriving at the final answer. It mimics how humans often solve complex problems by breaking them down into smaller, manageable steps.&lt;/p&gt;

&lt;p&gt;Here's an example of a CoT question and response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question:
"Sarah has 7 apples. 
She gives 3 apples to her friend and then buys 5 more. 
How many apples does Sarah have now?"

Model's Response:

"Sarah starts with 7 apples."
"She gives 3 apples away, so she has 7 - 3 = 4 apples left."
"She buys 5 more apples, so now she has 4 + 5 = 9 apples."
Answer: "Sarah has 9 apples."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shots are examples that demonstrate to the model the correct way to answer the problem. "5-shot" means five(5) examples and "0-shot" means no examples. &lt;/p&gt;

&lt;p&gt;A high 0-shot score demonstrates that the model has a strong ability to generalize its knowledge to new tasks or questions it hasn't seen before. &lt;/p&gt;

&lt;p&gt;On the other hand, a high 5-shot (or any number greater than 0) score shows that the model is good at learning from a few examples and applying that knowledge to similar tasks.&lt;/p&gt;

&lt;p&gt;So, what's the key difference between "n-shot" and "n-shot CoT"?&lt;/p&gt;

&lt;p&gt;n-shot asks for a direct answer without explicit reasoning.&lt;br&gt;
n-shot CoT encourages the model to show its work and reasoning process.&lt;/p&gt;

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

&lt;p&gt;Hopefully by understanding these benchmarks, you'll be better equipped to interpret the ever-evolving LLM landscape and make informed decisions about which models might be most suitable for your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/" rel="noopener noreferrer"&gt;What is an LLM?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.anthropic.com/news/claude-3-family" rel="noopener noreferrer"&gt;Claude 3 benchmarks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ibm.com/topics/chain-of-thoughts#:~:text=Chain%20of%20thought%20prompting%20is,steps%20towards%20a%20final%20resolution." rel="noopener noreferrer"&gt;What is Chain of Thoughts?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.confident-ai.com/blog/llm-benchmarks-mmlu-hellaswag-and-beyond" rel="noopener noreferrer"&gt;LLM Benchmarks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://symbl.ai/developers/blog/an-in-depth-guide-to-benchmarking-llms/" rel="noopener noreferrer"&gt;An in-depth guide to LLM benchmarking&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>beginners</category>
    </item>
    <item>
      <title>iOS: The System Architecture</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Sun, 04 Aug 2024 13:13:44 +0000</pubDate>
      <link>https://forem.com/hmcodes/ios-the-system-architecture-3hmm</link>
      <guid>https://forem.com/hmcodes/ios-the-system-architecture-3hmm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After covering &lt;a href="https://dev.to/hmcodes/the-android-architecture-3b07"&gt;Android's system architecture&lt;/a&gt;, I wanted to understand the architecture of its biggest rival, iOS. This article aims to analyze each layer of iOS's system architecture (above the hardware) in a digestible format. Let's begin.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun fact: iOS (for mobile devices) and OS X (now called MacOS) have similar architectures. The main difference is at the topmost layer because people interact with mobile devices and laptops differently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Kernel &amp;amp; Device Drivers
&lt;/h2&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%2Feynjl2v6xj7h7xb67x26.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%2Feynjl2v6xj7h7xb67x26.png" alt="Kernel &amp;amp; Device Drivers" width="454" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The iOS kernel manages system resources, processes, memory, security, and device interactions. It acts as an intermediary between hardware and software. If you've interacted with Apple products or services you may have heard the terms 'Mach' or 'Darwin'. This layer is where both of these components reside.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mach
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Apple documentation uses the term 'Kernel' somewhat differently than you might expect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mach is a microkernel which manages processor resources such as CPU usage and memory, handles scheduling, provides memory protection, and offers other services to the rest of the operating-system layers. In the kernel architecture, Mach (the microkernel) is one of the components of the kernel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Darwin
&lt;/h3&gt;

&lt;p&gt;The kernel, along with other core parts of the operating system, is collectively referred to as Darwin. Darwin is based on BSD and includes Mach and other components.&lt;/p&gt;

&lt;p&gt;Device drivers complement the kernel by translating between hardware devices and the OS. They provide hardware abstraction, handle I/O operations etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core OS
&lt;/h2&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%2F8hjreqh82kaovsqa0yda.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%2F8hjreqh82kaovsqa0yda.png" alt="Core OS" width="455" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This layer abstracts many of the complexities of the kernel, providing a more accessible interface for higher-level software. These services are typically used for tasks that require direct interaction with system resources or low-level operations, but are not directly exposed to applications. Some components at this layer are OpenCL and System Configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Services
&lt;/h2&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%2Fe2wjp1il8ymdrtahspdp.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%2Fe2wjp1il8ymdrtahspdp.png" alt="Core Services" width="455" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Core Services often build upon the functionality provided by Core OS to offer more complex and application-specific features. Core Services provide essential services to apps but have no direct bearing on the app’s user interface. Some components at this layer include the Accounts framework, Social framework and MapKit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Media Layer
&lt;/h2&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%2Fn6a3m6d129mew57kcwm7.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%2Fn6a3m6d129mew57kcwm7.png" alt="Media Layer" width="455" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Media layer handles all the audio, video, graphics, and animation services required by applications. Components like Core graphics, Core audio and OpenGL are found at this layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cocoa application layer
&lt;/h2&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%2Fg1la6pu2yzhvhcm12z1s.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%2Fg1la6pu2yzhvhcm12z1s.png" alt="Cocoa application layer" width="455" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This layer is primarily responsible for the appearance of apps and their responsiveness to user actions. It provides the frameworks needed to build user interfaces and interact with device features. Here is where most developers will spend the majority of their time. Some components at this layer include UIKit, HealthKit and HomeKit.&lt;/p&gt;

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

&lt;p&gt;We can see that there are some similarities between iOS's architecture and that of Android. Each layer of the iOS architecture plays a vital role in delivering the experience that users have come to expect from Apple devices. Hopefully, this post clarified the role of each layer and helped you to get a better understanding of how everything fits together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/CoreOSLayer/CoreOSLayer.html" rel="noopener noreferrer"&gt;Core OS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/Architecture/Architecture.html" rel="noopener noreferrer"&gt;OS X Kernel Architecture Overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Ko4V3G4NqII" rel="noopener noreferrer"&gt;Mac world&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/IOS" rel="noopener noreferrer"&gt;iOS&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>mobile</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Android: Version types</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Sun, 28 Jul 2024 20:46:39 +0000</pubDate>
      <link>https://forem.com/hmcodes/android-version-types-34nf</link>
      <guid>https://forem.com/hmcodes/android-version-types-34nf</guid>
      <description>&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%2Fm155o9hzoqhfww9d0axm.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%2Fm155o9hzoqhfww9d0axm.png" alt="Android studio screenshot" width="697" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Android, you'll encounter various version numbers and terms that can seem confusing at first. This post aims to clarify the different types of versions in the Android ecosystem, helping you understand their purposes and relationships.&lt;/p&gt;

&lt;p&gt;The version types I want to address are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OS version&lt;/li&gt;
&lt;li&gt;API level&lt;/li&gt;
&lt;li&gt;minSdkVersion&lt;/li&gt;
&lt;li&gt;compileSdkVersion&lt;/li&gt;
&lt;li&gt;targetSdkVersion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OS Version
&lt;/h2&gt;

&lt;p&gt;The Android OS version refers to the release version of the Android operating system. These versions are typically named after desserts and are associated with a version number. For example, Android 8.0 had the nickname Oreo, the tastiest snack in the western hemisphere. As of writing, the latest stable release is Android 14, with Android 15 in development.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Level
&lt;/h2&gt;

&lt;p&gt;The API level is an integer value that uniquely identifies the version of the Android framework API offered by a version of the Android OS. &lt;br&gt;
Each Android OS version is associated with one or more API levels.&lt;br&gt;
For example, Android 8.0 corresponds to API level 26 - 27.&lt;br&gt;
This is one reason why the API level is used in minSdkVersion, compileSdkVersion, targetSdkVersion and other settings instead of the OS version.&lt;/p&gt;

&lt;h2&gt;
  
  
  minSdkVersion
&lt;/h2&gt;

&lt;p&gt;The minSdkVersion is a value set in your app's build configuration that specifies the minimum API level required to run your application. It ensures that your app isn't installed on devices running an older, unsupported Android version. For example, if you set minSdkVersion to 26, your app will only be available to devices running Android 8.0 (Oreo) or higher.&lt;/p&gt;

&lt;p&gt;It's recommended to choose the lowest API level that your app can support while still providing a good user experience. Consider factors like the features you need and the percentage of devices running each Android version. Setting it too high will limit your app's reach, while setting it too low might prevent you from using newer features.&lt;/p&gt;

&lt;h2&gt;
  
  
  compileSdkVersion
&lt;/h2&gt;

&lt;p&gt;The compileSdkVersion is the version of Android that your app is compiled against. For example, if you set compileSdkVersion to 26, you can use APIs up to, and including, those in Android 8.0 in your code.&lt;/p&gt;

&lt;p&gt;It's generally recommended to always compile with the latest stable SDK version to ensure you have access to the newest APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  targetSdkVersion
&lt;/h2&gt;

&lt;p&gt;The targetSdkVersion indicates the highest API level on which you've tested your application. It tells the system that you've tested your app on this version, allowing the system to enable compatibility behaviours for higher API levels.&lt;/p&gt;

&lt;p&gt;It's recommended to keep your targetSdkVersion as high as possible to ensure your app can take advantage of the latest Android features and optimizations.&lt;/p&gt;

&lt;p&gt;Also, Google has a target API level requirement which indicates the minimum acceptable targetSdkVersion for apps that can be submitted to the Play Store.&lt;/p&gt;

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

&lt;p&gt;Writing this post made me hungry, but it was worth it. I hope these versions are much easier to understand now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Android_version_history" rel="noopener noreferrer"&gt;Android version history&lt;/a&gt;&lt;br&gt;
&lt;a href="https://support.google.com/googleplay/android-developer/answer/11926878?hl=en" rel="noopener noreferrer"&gt;Target API level requirements for Google Play apps&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.android.com/guide/topics/manifest/uses-sdk-element.html" rel="noopener noreferrer"&gt;uses-sdk-element&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobile</category>
      <category>androiddev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Android: The System Architecture</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Sun, 21 Jul 2024 15:49:33 +0000</pubDate>
      <link>https://forem.com/hmcodes/the-android-architecture-3b07</link>
      <guid>https://forem.com/hmcodes/the-android-architecture-3b07</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After working with React Native, I was curious about how the Android system worked. This guide aims to demystify the Android system architecture.&lt;/p&gt;

&lt;p&gt;The Android system is a layered architecture, with each layer building upon the capabilities of the layers below it. Let's examine each layer in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware
&lt;/h2&gt;

&lt;p&gt;At the foundation of the Android system lies the physical hardware - the tangible components that form the device's infrastructure. This includes the Central Processing Unit (CPU), Graphics Processing Unit (GPU), Random Access Memory (RAM) etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kernel
&lt;/h2&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%2Fvstztp1ro6y6gljaic6y.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%2Fvstztp1ro6y6gljaic6y.png" alt="Kernel &amp;amp; Hardware" width="532" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The kernel serves as the core of the Android operating system, acting as an intermediary between the hardware and higher-level software components. Some of its major responsibilities include process management, memory management and device driver management.&lt;br&gt;
The kernel also provides essential drivers for hardware components such as the camera, keypad, display and Wi-Fi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native Daemons &amp;amp; Libraries
&lt;/h2&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%2Fxdodswr2v0d9z6qzvi6j.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%2Fxdodswr2v0d9z6qzvi6j.png" alt="Native daemons" width="532" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Native daemons, written in C and C++, are long-running processes that operate in the background on system startup. They primarily interact with the kernel and are responsible for handling critical system tasks. An example of a native daemon is &lt;code&gt;init&lt;/code&gt; which is responsible for initializing the Android system.&lt;/p&gt;

&lt;p&gt;Native libraries, also written in C and C++, provide core functionalities to both the Android system and third-party apps. An example of a native library is libc (the C library), which provides basic C library functions for memory management, string manipulation, and file I/O.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware Abstraction Layer (HAL)
&lt;/h2&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%2Fuoo7ic96c54gw5kvfiwr.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%2Fuoo7ic96c54gw5kvfiwr.png" alt="Hardware abstraction layer" width="532" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The HAL sits above the kernel, allowing Android to be hardware-agnostic. This abstraction enables a consistent API regardless of the underlying hardware, facilitating improved compatibility across diverse Android devices.&lt;/p&gt;

&lt;p&gt;Examples of HAL implementations include Bluetooth HAL and Camera HAL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android Runtime
&lt;/h2&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%2F2rbqiwcahdaa3gcvayw4.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%2F2rbqiwcahdaa3gcvayw4.png" alt="Android Runtime" width="532" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Android Rutnime (ART) is responsible for executing and managing applications written in Java. It translates bytecode (compiled code from developers) into machine code that the device's processor can understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Services
&lt;/h2&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%2F4t420x5k1dbrr71sbcms.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%2F4t420x5k1dbrr71sbcms.png" alt="System services" width="533" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Android System Services are fundamental components that manage various aspects of the Android environment. They operate in the background, ensuring smooth system operation and providing essential functionalities to applications. Examples include the &lt;br&gt;
ActivityManagerService, the WindowManagerService and the PowerManagerService.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android Framework
&lt;/h2&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%2Fgl2omfkkp504yvrronf6.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%2Fgl2omfkkp504yvrronf6.png" alt="Android Framework" width="533" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Android Framework sits at the top. It provides high-level services to applications in the form of Java classes, interfaces and precompiled code, thereby abstracting complexity of the underlying systems. Some of the major components include the Activity Manager, the Window Manager and Content Providers. &lt;/p&gt;

&lt;p&gt;Some of the framework is available through the use of the Android API, and other portions of the framework can only be accessed by the System API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Android API and System APIs
&lt;/h3&gt;

&lt;p&gt;The Android API, sometimes referred to as the framework API, is the public interface that app developers use to interact with the Android system. It includes functionalities for tasks such as UI creation, data storage, and hardware interaction.&lt;/p&gt;

&lt;p&gt;System APIs, on the other hand, are interfaces intended for use by the Android system and privileged apps. They provide access to lower-level functionalities and are not available to third-party applications for security reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applications
&lt;/h2&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%2F0fry71gduy0u9en71iik.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%2F0fry71gduy0u9en71iik.png" alt="Applications" width="533" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the very top of the stack are the applications themselves, both system apps and user-installed apps. These utilize the APIs provided by the Android Framework to interact with the underlying system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Special mention: Binder IPC Proxies
&lt;/h2&gt;

&lt;p&gt;The Binder Inter-Process Communication (IPC) mechanism facilitates efficient and secure communication between different processes and components within the Android system. It enables interaction between applications and system services.&lt;/p&gt;

&lt;p&gt;For example, when an app requests location data, it communicates with the LocationManagerService via Binder IPC. The service processes the request and returns the location data back to the app, all mediated by the Binder mechanism.&lt;/p&gt;

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

&lt;p&gt;Android's layered architecture is pretty fascinating when you dive into it. From the hardware all the way up to the apps we use daily, each component plays its part. Hopefully, this post made it easier to understand what's going on behind the scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://source.android.com/docs/core/architecture" rel="noopener noreferrer"&gt;https://source.android.com/docs/core/architecture&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.android.com/guide/platform#system-services" rel="noopener noreferrer"&gt;https://developer.android.com/guide/platform#system-services&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels" rel="noopener noreferrer"&gt;https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Android: Skins vs Launchers</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Thu, 18 Jan 2024 17:32:03 +0000</pubDate>
      <link>https://forem.com/hmcodes/android-skins-vs-launchers-58g1</link>
      <guid>https://forem.com/hmcodes/android-skins-vs-launchers-58g1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you're like me, the first time you heard about skins and launchers, you were curious to learn the difference between the two. However, I found that many sources didn't explain what they were and the difference between them clearly. So, I decided to do some research and take a swing at it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are skins?
&lt;/h2&gt;

&lt;p&gt;In the world of Android, you have multiple manufacturers that like to add their own flavour to the stock operating system, often referred to as "Stock Android".&lt;/p&gt;

&lt;p&gt;Skins are UI-focused updates made by the manufacturers to the device's operating system, which is based on Stock Android. I say UI-focused because skins can include changes to things other than the UI. &lt;/p&gt;

&lt;p&gt;For example, Samsung's One UI has camera modes like "Single Take" that are not available on Stock Android.&lt;/p&gt;

&lt;p&gt;However, the UI changes are often the most noticeable aspect of a skin.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are launchers?
&lt;/h2&gt;

&lt;p&gt;Launchers are third-party applications that also provide UI enhancements and additional functionalities. Given that they are third-party applications, you can download them from the Google Play Store just like Instagram and TikTok.&lt;/p&gt;

&lt;h2&gt;
  
  
  What don't skins do?
&lt;/h2&gt;

&lt;p&gt;Skins don't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restrict access to the core features of the Stock Android OS. This means that you'll still have access to basic features like the Google Play Store, Android core apps, making calls, texting, and browsing the web.&lt;/li&gt;
&lt;li&gt;Directly update the Android version on the device.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What don't launchers do?
&lt;/h2&gt;

&lt;p&gt;Launchers don't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the Android version on the device.&lt;/li&gt;
&lt;li&gt;Alter the device's firmware.&lt;/li&gt;
&lt;li&gt;Provide security updates or patches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are some popular skins?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Samsung's One UI&lt;/strong&gt;: Available on Samsung Galaxy devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel UI&lt;/strong&gt;: Found on Google Pixel phones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIUI&lt;/strong&gt;: Used on Xiaomi and Redmi phones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are some popular launchers?
&lt;/h2&gt;

&lt;p&gt;Some of the most popular launchers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nova Launcher&lt;/strong&gt;: Consistently rated one of the best and most powerful launchers, offering extensive customization options and features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Niagara Launcher&lt;/strong&gt;: A minimalist launcher focusing on one-handed usability and information density.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hyperion Launcher&lt;/strong&gt;: A free and open-source launcher with a clean and customizable interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In the world of Android, customization reigns supreme. Skins and Launchers are two of the most popular ways that manufacturers and end users customize their devices and their Android experience. They are similar in some ways, but different in others and I hope it's clearer now. If this was helpful and if you want to support me, feel free to &lt;a href="https://www.buymeacoffee.com/hmcodes" rel="noopener noreferrer"&gt;buy me a coffee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to see more launchers, you can &lt;a href="https://www.androidpolice.com/best-android-launchers/#nova-launcher-prime" rel="noopener noreferrer"&gt;visit here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobile</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to test the Hidden API (from Material UI)</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Wed, 14 Jun 2023 23:06:53 +0000</pubDate>
      <link>https://forem.com/hmcodes/how-to-activate-the-hidden-api-from-material-ui-in-a-jest-test-n1n</link>
      <guid>https://forem.com/hmcodes/how-to-activate-the-hidden-api-from-material-ui-in-a-jest-test-n1n</guid>
      <description>&lt;p&gt;If you want to hide or display the element tree nested inside &lt;a href="https://mui.com/material-ui/api/hidden/" rel="noopener noreferrer"&gt;&amp;lt;Hidden&amp;gt;&lt;/a&gt; tags  for a jest test, here's how it can be done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Let's say that we're testing if "Hey" is rendered correctly:&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Testing Hidden API&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="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hidden&lt;/span&gt; &lt;span class="nx"&gt;xsDown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hey&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Hidden&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'Hey' is visible&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;Note: The &lt;code&gt;render&lt;/code&gt; method is imported from @testing-library/react&lt;/p&gt;

&lt;p&gt;If we want 'Hey' to be visible, we need the &lt;code&gt;xsDown&lt;/code&gt; property of the &amp;lt;Hidden&amp;gt; component to evaluate to &lt;code&gt;false&lt;/code&gt; when the test runs.  &lt;/p&gt;

&lt;p&gt;From Material UI's &lt;a href="https://mui.com/material-ui/customization/breakpoints/" rel="noopener noreferrer"&gt;breakpoint documentation&lt;/a&gt;, we can see that we need to simulate the window's &lt;code&gt;innerWidth&lt;/code&gt; being a value greater than or equal to 600px.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it work
&lt;/h2&gt;

&lt;p&gt;While you may think that only changing the window's dimensions in the manner below is sufficient, this will not produce the desired result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&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;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&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 key is to mock the window's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia" rel="noopener noreferrer"&gt;&lt;code&gt;matchMedia()&lt;/code&gt;&lt;/a&gt; method.&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Testing Hidden API&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="nf"&gt;beforeEach&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;matchMedia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(max-width: 599px)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="na"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="na"&gt;removeListener&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&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;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hidden&lt;/span&gt; &lt;span class="nx"&gt;xsDown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hey&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Hidden&lt;/span&gt;&lt;span class="err"&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hey is visible&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;h2&gt;
  
  
  Why does this work?
&lt;/h2&gt;

&lt;p&gt;When the &amp;lt;Hidden&amp;gt; component is rendered, it calls the &lt;code&gt;matchMedia&lt;/code&gt; function with the corresponding media query for each specified breakpoint . For example, for &lt;code&gt;xsDown&lt;/code&gt;, it would use the media query &lt;code&gt;(max-width: 599px)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;PS: This is why it wasn't necessary to include the previous logic (window.innerWidth = 600; ...) to make this test work. However, depending on your test you may need to change your dimensions in such a manner.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;matchMedia&lt;/code&gt; function returns a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList" rel="noopener noreferrer"&gt;&lt;code&gt;MediaQueryList&lt;/code&gt;&lt;/a&gt; object, which represents the result of the media query evaluation. The &lt;code&gt;matches&lt;/code&gt; property of this object indicates whether the media query condition evaluates to &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Hidden&lt;/code&gt; component listens for changes in the &lt;code&gt;matches&lt;/code&gt; property of the &lt;code&gt;MediaQueryList&lt;/code&gt; objects for each breakpoint. &lt;/p&gt;

&lt;p&gt;Whenever the &lt;code&gt;matches&lt;/code&gt; property changes (i.e., when the viewport size or browser window is resized), the &lt;code&gt;Hidden&lt;/code&gt; component updates its state based on the new visibility status for each breakpoint.&lt;/p&gt;

&lt;p&gt;So, by returning &lt;code&gt;false&lt;/code&gt; for the &lt;code&gt;matches&lt;/code&gt; property in the mock implementation we make the children of the &amp;lt;Hidden&amp;gt; component visible. If we wanted to hide the children of the &amp;lt;Hidden&amp;gt; component then we would return &lt;code&gt;true&lt;/code&gt; for the &lt;code&gt;matches&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;If you liked this article, then please &lt;a href="https://www.buymeacoffee.com/hmcodes" rel="noopener noreferrer"&gt;support me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>jest</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Tidbit: com.android.ide.common.signing.KeytoolException: Failed to read key &lt;alias&gt; from store "C:\..\&lt;keystore-name&gt;.keystore"</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Mon, 02 Jan 2023 17:14:33 +0000</pubDate>
      <link>https://forem.com/hmcodes/tidbit-failed-to-read-key-from-store-4b07</link>
      <guid>https://forem.com/hmcodes/tidbit-failed-to-read-key-from-store-4b07</guid>
      <description>&lt;p&gt;When attempting to create the release bundle for a React Native app, I followed the steps in the (guide)[&lt;a href="https://reactnative.dev/docs/signed-apk-android" rel="noopener noreferrer"&gt;https://reactnative.dev/docs/signed-apk-android&lt;/a&gt;] and generated the keystore. However, when I ran this command to create the release AAB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd android
./gradlew bundleRelease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I encountered an error message with the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* What went wrong:
Execution failed for task ':app:packageRelease'.
&amp;gt; A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
   &amp;gt; com.android.ide.common.signing.KeytoolException: Failed to read key &amp;lt;alias&amp;gt; from store "C:\Users\...\&amp;lt;keystore-name&amp;gt;.keystore": Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given that there was no instruction from the CLI to create a key password, this might be a bit confusing.&lt;br&gt;
The solution is to use the keystore password in the key password field in your build.gradle file. For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=&amp;lt;keystore-password&amp;gt;
MYAPP_UPLOAD_KEY_PASSWORD=&amp;lt;keystore-password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason why this works is that different store and key passwords are not supported for PKCS12 keystores.&lt;/p&gt;

&lt;p&gt;If you liked this article, then please &lt;a href="https://www.buymeacoffee.com/hmcodes" rel="noopener noreferrer"&gt;support me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>How to test third-party React Native components using React Native Testing Library</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Fri, 15 Jul 2022 22:48:10 +0000</pubDate>
      <link>https://forem.com/hmcodes/how-to-test-third-party-react-native-components-using-react-native-testing-library-g58</link>
      <guid>https://forem.com/hmcodes/how-to-test-third-party-react-native-components-using-react-native-testing-library-g58</guid>
      <description>&lt;p&gt;Testing third-party React Native components using Jest and React Native Testing Library can be really frustrating. I remember tryin every event I saw in the &lt;a href="https://callstack.github.io/react-native-testing-library/docs/api#fireevent" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to no avail. &lt;code&gt;press&lt;/code&gt;,  &lt;code&gt;click&lt;/code&gt;, &lt;code&gt;scroll&lt;/code&gt;, the whole nine yards. &lt;/p&gt;

&lt;p&gt;However, through &lt;del&gt;blood, sweat and tears&lt;/del&gt; trial and error I managed to figure out a general approach that works and I wanted to share it to save others the stress. &lt;/p&gt;

&lt;p&gt;I'm going to illustrate the approach by demonstrating simple tests on a component from the &lt;code&gt;react-native-picker-select&lt;/code&gt; package. &lt;/p&gt;

&lt;h3&gt;
  
  
  Locating the component in the tree
&lt;/h3&gt;

&lt;p&gt;The first step for most tests is to locate the component(s) that will be involved. The problem is that not every third-party component provides the option to directly set a prop such as &lt;code&gt;testID&lt;/code&gt;, so I had to get creative.&lt;/p&gt;

&lt;p&gt;We start by wrapping the component within a pair of &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt; tags and setting a prop on the parent &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt;, such as &lt;code&gt;testID&lt;/code&gt;. Afterwards, we can locate the component by accessing the &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt;'s children. Here's some sample code to demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//CustomPickerSelect.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&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="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RNPickerSelect&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;react-native-picker-select&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;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;testID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'picker-select-parent'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RNPickerSelect&lt;/span&gt;
                &lt;span class="na"&gt;onValueChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//CustomPickerSelect.test.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&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="s1"&gt;@testing-library/react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&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;./CustomPickerSelect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Testing CustomPickerSelect&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;picker-select-parent&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;picker&lt;/code&gt; is the &lt;code&gt;ReactTestInstance&lt;/code&gt; that represents the third-party component &lt;code&gt;RNPickerSelect&lt;/code&gt; in the rendered tree. &lt;/p&gt;

&lt;h3&gt;
  
  
  Firing events
&lt;/h3&gt;

&lt;p&gt;For third-party components, the names of the events (or event handlers) which elicit a response are usually listed in their props. The props are usually available in the documentation, but this is not always the case. The documentation may also be outdated, so it helps to see for yourself which props are available by logging the &lt;code&gt;.props&lt;/code&gt; property of the &lt;code&gt;ReactTestInstance&lt;/code&gt;. Let's do this now:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&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="s1"&gt;@testing-library/react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&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;./CustomPickerSelect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Testing CustomPickerSelect&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;picker-select-parent&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;picker props: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;picker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&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;Here's a screenshot of the log:&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%2F8x0ykeqxadelzgevbeu2.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%2F8x0ykeqxadelzgevbeu2.png" alt="Screenshot 1" width="597" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a brief detour to discuss the main tool that we'll be using: &lt;code&gt;fireEvent&lt;/code&gt;. The &lt;code&gt;fireEvent&lt;/code&gt; method provided by React Native Testing Library has the following syntax:&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;fireEvent&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="nx"&gt;ReactTestInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventName&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="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="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the meaning of the &lt;code&gt;data&lt;/code&gt; parameter is unclear to you, it actually represents the argument(s) that will be passed to the event handler that is being invoked. &lt;/p&gt;

&lt;p&gt;The challenge is determining the right value to use for the &lt;code&gt;eventName&lt;/code&gt; argument. This is where we reference the props for the &lt;code&gt;ReactTestInstance&lt;/code&gt; that were logged earlier. The event handlers are usually prefixed by "on-", for example &lt;code&gt;onPress&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Here are the event handlers for our &lt;code&gt;ReactTestInstance&lt;/code&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%2Fm7ozmh43alb9yv7b4sw8.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%2Fm7ozmh43alb9yv7b4sw8.png" alt="Screenshot 2" width="581" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's make a few additions to the &lt;code&gt;CustomPickerSelect.jsx&lt;/code&gt; component to facilitate the testing of the &lt;code&gt;onValueChange&lt;/code&gt; event handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&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="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RNPickerSelect&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;react-native-picker-select&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;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&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;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;testID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'picker-select-parent'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RNPickerSelect&lt;/span&gt;
                &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onValueChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&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="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's invoke the &lt;code&gt;onValueChange&lt;/code&gt; event handler and check to make sure that everything works as expected:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&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="s1"&gt;@testing-library/react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&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;./CustomPickerSelect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Testing CustomPickerSelect&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;picker-select-parent&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;picker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onValueChange&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;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;picker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&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="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&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;It's generally not encouraged to assert on implementation details, but it can't hurt to know how to do this ;). &lt;/p&gt;

&lt;p&gt;If you want to conduct other tests, you can make the necessary changes. For example, here's some code to test if a callback function passed in as a prop to the &lt;code&gt;CustomPickerSelect&lt;/code&gt; component is invoked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&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="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RNPickerSelect&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;react-native-picker-select&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;CustomPickerSelect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;setValueCallback&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="kd"&gt;const&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;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;testID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'picker-select-parent'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RNPickerSelect&lt;/span&gt;
                &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onValueChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&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="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nf"&gt;setValueCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&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="s1"&gt;@testing-library/react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CustomPickerSelect&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;./CustomPickerSelect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Testing CustomPickerSelect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&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;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CustomPickerSelect&lt;/span&gt; 
       &lt;span class="nx"&gt;setValueCallback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mockCallback&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;picker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;picker-select-parent&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;picker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onValueChange&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;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockCallback&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&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;That's it for now. Thanks for reading and share this with a friend if this helped.&lt;/p&gt;

&lt;p&gt;If you liked this article, then please &lt;a href="https://www.buymeacoffee.com/hmcodes" rel="noopener noreferrer"&gt;support me&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-native-picker-select" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-native-picker-select&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://callstack.github.io/react-native-testing-library/docs/api#fireevent" rel="noopener noreferrer"&gt;https://callstack.github.io/react-native-testing-library/docs/api#fireevent&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>testing</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What's hindering React Native now?</title>
      <dc:creator>Hodeem</dc:creator>
      <pubDate>Wed, 13 Jul 2022 12:46:00 +0000</pubDate>
      <link>https://forem.com/hmcodes/whats-hindering-react-native-now-16d3</link>
      <guid>https://forem.com/hmcodes/whats-hindering-react-native-now-16d3</guid>
      <description>&lt;p&gt;I &lt;em&gt;really&lt;/em&gt; like developing mobile applications with React Native, but I wasn't seeing much evidence of widespread adoption. This made me wonder, "Why isn't React Native more popular?"&lt;/p&gt;

&lt;p&gt;This question led me to research the main obstacles to React Native's widespread adoption. After reviewing a few articles, I noticed a few common themes among complaints by both developers and teams. &lt;/p&gt;

&lt;p&gt;Please note that the following list of themes is based on articles written between 2017 and 2018. Also, this list is not meant to be an exhaustive list of React Native's shortcomings. &lt;/p&gt;

&lt;p&gt;&lt;u&gt;What are common concerns about using React Native?&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Knowledge of 3 platforms is sometimes required to implement custom features.&lt;/li&gt;
&lt;li&gt;Heavy investment in bridging infrastructure may be necessary to implement custom features.&lt;/li&gt;
&lt;li&gt;The animations and gestures tend to be non-performant.&lt;/li&gt;
&lt;li&gt;Implementing in-app navigation isn't easy.&lt;/li&gt;
&lt;li&gt;There tends to be a slow initialisation and first-render time.&lt;/li&gt;
&lt;li&gt;There is a lack of parallel threading or multiprocessing support.&lt;/li&gt;
&lt;li&gt;It can be difficult to debug errors because stack traces don't jump between React Native and native.&lt;/li&gt;
&lt;li&gt;JavaScript is untyped.&lt;/li&gt;
&lt;li&gt;React Native apps can have trouble rendering long lists performantly.&lt;/li&gt;
&lt;li&gt;Android bundle size can be large.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you've been developing with React Native recently you may have noticed that there have been major developments in more than one of these areas. &lt;/p&gt;

&lt;p&gt;For example, &lt;a href="https://swmansion.com/" rel="noopener noreferrer"&gt;Software Mansion&lt;/a&gt; has made significant contributions to animations and gesture-handling with their &lt;code&gt;react-native-reanimated&lt;/code&gt; and &lt;code&gt;react-native-gesture-handler&lt;/code&gt; packages. &lt;/p&gt;

&lt;p&gt;More recently, Shopify have taken a stab at the issue of rendering long lists performantly by open-sourcing their &lt;a href="https://github.com/Shopify/flash-list" rel="noopener noreferrer"&gt;flash-list package&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;The questions I have for the broader mobile development community are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Out of the 10 concerns highlighted above, how many do you believe are still valid?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What do you believe are the top &lt;strong&gt;technical&lt;/strong&gt; reasons preventing teams or companies from adopting React Native for mobile app development today?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you liked this article, then please &lt;a href="https://www.buymeacoffee.com/hmcodes" rel="noopener noreferrer"&gt;support me&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Sources&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c" rel="noopener noreferrer"&gt;https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838" rel="noopener noreferrer"&gt;https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88" rel="noopener noreferrer"&gt;https://medium.com/airbnb-engineering/building-a-cross-platform-mobile-team-3e1837b40a88&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a" rel="noopener noreferrer"&gt;https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.simform.com/blog/react-native-limitations-app-development/" rel="noopener noreferrer"&gt;https://www.simform.com/blog/react-native-limitations-app-development/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.theregister.com/2020/01/30/shopify_shifts_its_mobile_development_to_react_native/" rel="noopener noreferrer"&gt;https://www.theregister.com/2020/01/30/shopify_shifts_its_mobile_development_to_react_native/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
