<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nour Abdou</title>
    <description>The latest articles on DEV Community by Nour Abdou (@nour_abdou).</description>
    <link>https://dev.to/nour_abdou</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%2F781506%2Ffc156d0e-382e-4490-a583-b09aa6399228.jpeg</url>
      <title>DEV Community: Nour Abdou</title>
      <link>https://dev.to/nour_abdou</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nour_abdou"/>
    <language>en</language>
    <item>
      <title>React Native OTA Updates with Expo EAS: Step-by-Step Guide &amp; Best Practices</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Mon, 12 May 2025 17:25:41 +0000</pubDate>
      <link>https://dev.to/nour_abdou/react-native-ota-updates-with-expo-eas-step-by-step-guide-best-practices-1idk</link>
      <guid>https://dev.to/nour_abdou/react-native-ota-updates-with-expo-eas-step-by-step-guide-best-practices-1idk</guid>
      <description>&lt;p&gt;Mobile app development has entered an era where agility and speed are paramount. Traditional methods, which require submitting new versions to app stores for review and awaiting user downloads, can lead to significant delays.&lt;/p&gt;

&lt;p&gt;Over-the-air (OTA) updates provide a transformative solution by allowing you to push code changes directly to users’ devices, such as essential fixes, user interface improvements, and new features, thereby reducing downtime and enhancing the overall user experience. &lt;/p&gt;

&lt;p&gt;In this article, we'll delve into how OTA updates work, discuss their benefits and challenges, and provide a step-by-step guide on implementing it within the Expo ecosystem. &lt;/p&gt;




&lt;h2&gt;
  
  
  In-Depth Analysis of OTA Updates: Capabilities, Benefits, and Limitations
&lt;/h2&gt;

&lt;h4&gt;
  
  
  📌 Capabilities of OTA Updates
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Immediate Bug Fixes: Quickly resolve critical issues and deploy fixes without waiting for the app store review process. This minimizes downtime and reduces the risk of prolonged user impact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rapid Feature Delivery: Roll out new features in real time, enabling a more agile development cycle and gathering user feedback sooner. This accelerates the iterative process and improves overall product quality. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Swift UI/UX Tweaks (JS Side): Make minor adjustments to the user interface or experience directly in the JS bundle. Users receive these changes instantly on their next app launch, ensuring that the app stays up-to-date. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instant Performance Improvements: Deploy performance enhancements immediately, directly benefiting the end-user experience without manual updates.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  📌 Benefits of OTA Updates
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Speed &amp;amp; Flexibility:  Users get fixes and new features right away, and you can update as frequently as needed, improving your product continuously without waiting for app store reviews.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhanced User Experience: With OTA updates, users always have the latest version of your app. No need for them to do anything, which keeps the experience smooth and consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cost-Effective: By minimizing the need for frequent app store submissions, you save time, money and resources, freeing you up to concentrate on creating even better things.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimized Downtime: These updates happen silently in the background! So users can continue using the app without interruption, and they'll see the improvements the next time they open the app. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  📌 Limitations of OTA Updates
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Native Code Constraints: While OTA updates are great for JavaScript and assets, any changes that touches the native parts of your app still needs a full update through the app store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complexity in Rollback: While pushing updates is rapid, rolling back to a previous version with OTA can be more complex compared to regular app store updates. Proper version control is essential to mitigate this risk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initial Setup Overhead: Getting OTA updates up and running in the first place takes some careful setup and know-how. The initial setup can be time-consuming and may require ongoing maintenance to keep the update process smooth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limited Control Over User Update Timing: Since OTA updates are applied on the next app launch, users might continue using an older version for a while, which isn't ideal for urgent fixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network Matters: The successful delivery of OTA updates depends on a reliable network connection. If the network is spotty, updates might be delayed or fail to download, leading to an inconsistent experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security is Key: While OTA updates enhance security by enabling rapid patch deployment, they also require robust security measures to ensure the update process itself is not compromised.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Configure EAS Update
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;p&gt;1- An Expo &lt;a href="https://expo.dev/signup" rel="noopener noreferrer"&gt;user account&lt;/a&gt;&lt;br&gt;
2- Your React Native project for sure.&lt;br&gt;
3- If your project is a bare React Native, it must use Expo CLI and extend the Expo Metro Config; 👉🏻 &lt;a href="https://docs.expo.dev/bare/installing-expo-modules/#manual-installation" rel="noopener noreferrer"&gt;Installing Expo modules guide&lt;/a&gt;.&lt;br&gt;
4- Your project must use the &lt;a href="https://docs.expo.dev/versions/latest/sdk/register-root-component/" rel="noopener noreferrer"&gt;registerRootComponent&lt;/a&gt; function instead of registerComponent.&lt;/p&gt;

&lt;p&gt;Now, follow these steps to set up EAS (Expo Application Services) Update:&lt;/p&gt;
&lt;h3&gt;
  
  
  1- Set up EAS Update
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Install the Latest EAS CLI&lt;/strong&gt;&lt;br&gt;
EAS CLI is the command line app you will use to interact with EAS services from your terminal. Install it globally:&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;eas&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cli&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Log in to Your Expo Account&lt;/strong&gt;&lt;br&gt;
If you are already signed in to an Expo account using Expo CLI, you can skip this step. If you are not, run the following command to log in:&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="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;
&lt;span class="c1"&gt;// then check whether you are logged:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;whoami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configure Your Project&lt;/strong&gt;&lt;br&gt;
Navigate to your project directory in terminal, initialize EAS Update for your project by running:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;configure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will update your &lt;code&gt;app.json&lt;/code&gt; file with the &lt;code&gt;runtimeVersion&lt;/code&gt; and &lt;code&gt;updates.url&lt;/code&gt; properties, and add the &lt;code&gt;extra.eas.projectId&lt;/code&gt; field if your project wasn't using any EAS services previously.&lt;/p&gt;

&lt;p&gt;You'll see the following changes to your native projects:&lt;/p&gt;

&lt;p&gt;➡️ Android&lt;br&gt;
Inside the &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt; file, you'll see the following additions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://u.expo.dev/your-project-id"/&amp;gt;
&amp;lt;meta-data android:name="expo.modules.updates.EXPO_RUNTIME_VERSION" android:value="@string/expo_runtime_version"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;EXPO_UPDATE_URL&lt;/code&gt; value should contain your project's ID.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;android/app/src/main/res/values/strings.xml&lt;/code&gt;, you'll see the &lt;code&gt;expo_runtime_version&lt;/code&gt; string entry in the resources object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;resources&amp;gt;
    &amp;lt;string name="app_name"&amp;gt;MyApp&amp;lt;/string&amp;gt;
    + &amp;lt;string name="expo_runtime_version"&amp;gt;1.0.0&amp;lt;/string&amp;gt;
&amp;lt;/resources&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;➡️  iOS&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;ios/project-name/Supporting/Expo.plist&lt;/code&gt;, you'll see the following additions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;key&amp;gt;EXUpdatesRuntimeVersion&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;1.0.0&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;EXUpdatesURL&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;https://u.expo.dev/your-project-id&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;EXUpdatesURL&lt;/code&gt; value should contain your project's ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Configuring a Channel
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Manually
&lt;/h4&gt;

&lt;p&gt;If you prefer not to use EAS Build for channel configuration, you can set the channel manually by updating both your &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; and &lt;strong&gt;Expo.plist&lt;/strong&gt; files.&lt;/p&gt;

&lt;p&gt;➡️ Android Configuration&lt;/p&gt;

&lt;p&gt;In your AndroidManifest.xml (located at android/app/src/main/AndroidManifest.xml), add the following meta-data tag:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt;
  &lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;meta-data&lt;/span&gt; &lt;span class="na"&gt;tag&lt;/span&gt; &lt;span class="na"&gt;configures&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;Expo&lt;/span&gt; &lt;span class="na"&gt;Updates&lt;/span&gt; &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
  &lt;span class="na"&gt;It&lt;/span&gt; &lt;span class="na"&gt;tells&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;app&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt; &lt;span class="na"&gt;include&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt; &lt;span class="na"&gt;custom&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt; &lt;span class="na"&gt;header&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expo-channel-name"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt; &lt;span class="na"&gt;every&lt;/span&gt; &lt;span class="na"&gt;update&lt;/span&gt; &lt;span class="na"&gt;check&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ensuring&lt;/span&gt; &lt;span class="na"&gt;that&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;correct&lt;/span&gt; &lt;span class="na"&gt;update&lt;/span&gt; &lt;span class="na"&gt;channel&lt;/span&gt; &lt;span class="na"&gt;is&lt;/span&gt; &lt;span class="na"&gt;used&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&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="nt"&gt;meta&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"expo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY"&lt;/span&gt; &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{&amp;amp;quot;expo-channel-name&amp;amp;quot;:&amp;amp;quot;your-channel-name&amp;amp;quot;}"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line sets the custom channel (replace "your-channel-name" with your actual channel name) that the app will use when checking for updates.&lt;/p&gt;

&lt;p&gt;➡️ iOS Configuration&lt;/p&gt;

&lt;p&gt;For iOS, update your Expo.plist file (located at ios/your-project-name/Supporting/Expo.plist) with the following configuration:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt;
  &lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;configuration&lt;/span&gt; &lt;span class="na"&gt;in&lt;/span&gt; &lt;span class="na"&gt;Expo&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plist&lt;/span&gt; &lt;span class="na"&gt;sets&lt;/span&gt; &lt;span class="na"&gt;up&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt; &lt;span class="na"&gt;updates&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
  &lt;span class="na"&gt;The&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt; &lt;span class="s"&gt;"expo-channel-name"&lt;/span&gt; &lt;span class="na"&gt;is&lt;/span&gt; &lt;span class="na"&gt;set&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"your-channel-name"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ensuring&lt;/span&gt; &lt;span class="na"&gt;that&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;app&lt;/span&gt;
  &lt;span class="na"&gt;contacts&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;correct&lt;/span&gt; &lt;span class="na"&gt;update&lt;/span&gt; &lt;span class="na"&gt;channel&lt;/span&gt; &lt;span class="na"&gt;on&lt;/span&gt; &lt;span class="na"&gt;your&lt;/span&gt; &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&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="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;EXUpdatesRequestHeaders&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;key&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="nt"&gt;dict&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="nt"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;expo-channel-name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;key&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="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;your-channel-name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;string&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="nt"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that the Expo updates module on iOS uses the specified channel.&lt;/p&gt;




&lt;p&gt;➡️  Alternative: Configuring via app.json&lt;/p&gt;

&lt;p&gt;If you prefer to let Expo generate this configuration automatically, you can set the requestHeaders property in your app.json. For example:&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="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expo&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;updates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// The URL where your app will fetch the OTA update manifest.&lt;/span&gt;
            &lt;span class="c1"&gt;// This is an Expo hosted URL&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&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;&amp;lt;https://u.expo.dev/&amp;gt;...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

            &lt;span class="c1"&gt;// Enables or disables OTA updates for the app.&lt;/span&gt;
            &lt;span class="c1"&gt;// Set to true to allow updates; false will disable OTA functionality.&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;enabled&lt;/span&gt;&lt;span class="dl"&gt;"&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;// Specifies the amount of time (in milliseconds) the app should wait&lt;/span&gt;
            &lt;span class="c1"&gt;// for an update to be downloaded before falling back to a cached version.&lt;/span&gt;
             &lt;span class="c1"&gt;// A value of 0 means the app will immediately use the cached update if available.&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fallbackToCacheTimeout&lt;/span&gt;&lt;span class="dl"&gt;"&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="c1"&gt;// Determines when the app checks for new updates.&lt;/span&gt;
            &lt;span class="c1"&gt;// "ON_LOAD" instructs the app to check for updates every time it launches.&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkAutomatically&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;ON_LOAD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

            &lt;span class="c1"&gt;// Additional HTTP headers that will be sent when the app requests an update.&lt;/span&gt;
            &lt;span class="c1"&gt;// In this case, the "expo-channel-name" header is used to designate the update channel,&lt;/span&gt;
           &lt;span class="c1"&gt;// allowing you to manage different release streams (e.g., test vs. production).&lt;/span&gt;

            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;requestHeaders&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expo-channel-name&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;your-channel-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"url" points to your manifest endpoint.&lt;/li&gt;
&lt;li&gt;"fallbackToCacheTimeout": 0 ensures that if the update isn’t immediately available, the app won’t wait.&lt;/li&gt;
&lt;li&gt;"checkAutomatically": "ON_LOAD" instructs the app to check for updates each time it launches.&lt;/li&gt;
&lt;li&gt;The "requestHeaders" property allows you to specify a channel (e.g., test or production).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then run:&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="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;expo&lt;/span&gt; &lt;span class="nx"&gt;prebuild&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will inject the proper configuration into both AndroidManifest.xml and Expo.plist.&lt;/p&gt;

&lt;p&gt;Note: Typically, you might use two channels: test and production.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. EAS Update Command Reference
&lt;/h3&gt;

&lt;p&gt;Below is a list of commonly used commands for managing updates, channels, and branches.&lt;/p&gt;

&lt;h4&gt;
  
  
  Manage updates
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Create and Publish a New Update:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your update message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fixes typo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View a Specific Update:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&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="nx"&gt;update&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Rollback an Update
&lt;/h5&gt;

&lt;p&gt;Rollback to a Previous Update:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;rollback&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Republish a Previous Update Within a Branch
&lt;/h5&gt;

&lt;p&gt;Republish by Group ID:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;republish&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Republish by Branch:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;republish&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;republish&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="nx"&gt;dbfd479f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;d981&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="nx"&gt;ce&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8774&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f2fbcc386aa&lt;/span&gt;
&lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;republish&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Manage Channels and Branches
&lt;/h5&gt;

&lt;p&gt;In EAS Update, a &lt;strong&gt;channel&lt;/strong&gt; acts as the "distribution pipeline" that delivers updates to your app, while a branch represents the mode or version stream—such as &lt;strong&gt;test&lt;/strong&gt; or &lt;strong&gt;production&lt;/strong&gt;—from which updates are sourced.&lt;/p&gt;

&lt;p&gt;By linking a branch to a channel, you control which updates reach specific user groups. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;test branch&lt;/strong&gt; connected to a test channel delivers updates to internal or beta testers.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;production branch&lt;/strong&gt; tied to a production channel sends updates to live users.
This separation ensures experimental changes stay confined to testing environments, protecting your production audience while enabling rapid iteration and feedback in development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Channels:&lt;/p&gt;

&lt;p&gt;View a Channel:&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="nx"&gt;eas&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;view&lt;/span&gt; &lt;span class="nx"&gt;production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List All Channels:&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="nx"&gt;eas&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;list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Branches:&lt;/p&gt;

&lt;p&gt;List All Branches:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View a Specific Branch and Its Updates:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete a Branch:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rename a Branch:&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="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;rename&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Add a hook to check for updates
&lt;/h3&gt;

&lt;p&gt;it's optional since you set &lt;code&gt;"checkAutomatically": "ON_LOAD",&lt;/code&gt;.&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Updates&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expo-updates&lt;/span&gt;&lt;span class="dl"&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;useisHasUpdates&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="nf"&gt;useEffect&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&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;try&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;isAvailable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Updates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkForUpdateAsync&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;isAvailable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Updates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchUpdateAsync&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;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error; checking for updates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="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;__DEV__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Create a build for your project
&lt;/h3&gt;

&lt;p&gt;Generate a production build with the runtime version and channel name, APK for Android and TestFlight for iOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Make changes locally
&lt;/h3&gt;

&lt;p&gt;After creating the build, you are ready to iterate on the project; make any desired changes to your project's JS, styling, or image assets.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. publish an update
&lt;/h3&gt;

&lt;p&gt;Use the &lt;code&gt;eas update&lt;/code&gt; command, and specify a name for the channel and a message to describe the update, as we talked before.&lt;/p&gt;

&lt;p&gt;📱 But how does publishing an update work?&lt;br&gt;
When you publish an update with the &lt;code&gt;eas update&lt;/code&gt; command, it generates a new update bundle and uploads it to the EAS servers. &lt;br&gt;
then it locates the correct branch to publish a new update according to channel name. It is similar to how Git commit works, where every commit is on a Git branch.&lt;/p&gt;
&lt;h3&gt;
  
  
  8. Test
&lt;/h3&gt;

&lt;p&gt;You can manually test the update by force closing and reopening a release build of your app up to two times to download and apply the update. &lt;br&gt;
Updates for non-development builds are automatically downloaded to the device in the background when the app starts up and makes a request for any new updates. The update will be applied after it is downloaded and the app is restarted.&lt;/p&gt;

&lt;p&gt;And Voilà, you are done now!! 🥂&lt;/p&gt;



&lt;p&gt;In some cases more control of how updates are sent to an app may be needed, and one option is to implement a custom updates server that adheres to the specification in order to serve update manifests and assets. 👇🏻&lt;/p&gt;
&lt;h3&gt;
  
  
  Configure a Custom Expo Updates Server
&lt;/h3&gt;

&lt;p&gt;You can set up your own custom Expo updates server to gain complete control over your app’s update distribution. Below are the implementation steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation Steps&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Custom Server and Implement Update Endpoints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Initialize the Project:&lt;br&gt;
Clone the official repository for the custom Expo updates server:&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="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/expo/custom-expo-updates-server.git&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;expo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This repo contains a basic server implementation built with Next.js. The key API endpoints are located in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pages/api/manifest.js – Handles the manifest file generation.&lt;/li&gt;
&lt;li&gt;pages/api/assets.js – Serves the asset bundles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These endpoints adhere to the Expo Updates protocol, allowing your app to fetch the latest update bundles.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set Up EAS Update Code Signing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 Code Signing:&lt;br&gt;
To ensure your updates are secure and verifiable, set up code signing by following the Expo documentation on &lt;a href="https://docs.expo.dev/eas-update/code-signing/" rel="noopener noreferrer"&gt;EAS Update Code Signing&lt;/a&gt;.&lt;br&gt;
This involves generating a signing certificate and configuring your server and app to use it, which protects your update bundles from tampering.&lt;/p&gt;

&lt;p&gt;💡 Uploading Credentials Manually&lt;br&gt;
To upload credentials from your local credentials.json file and have them managed by EAS, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your terminal at the root directory of your project.&lt;/li&gt;
&lt;li&gt;Run the command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;eas&lt;/span&gt; &lt;span class="nx"&gt;credentials&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;When prompted, select the desired platform.&lt;/li&gt;
&lt;li&gt;Choose the option:
"Credentials.json: Upload/Download credentials between EAS servers and your local json".&lt;/li&gt;
&lt;li&gt;Then select:
"Upload credentials from credentials.json to EAS".&lt;/li&gt;
&lt;li&gt;Repeat the process for another platform if needed by running the command again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach ensures that your credentials are safely managed by EAS, streamlining your build and deployment process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure Your React Native Mobile App&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Update the Configuration in app.json&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"updates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Expo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;hosted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;custom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;server's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;endpoint.&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://your-custom-server.com/manifest/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fallbackToCacheTimeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"checkAutomatically"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ON_LOAD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;used&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;verify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;authenticity&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OTA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bundle.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;should&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;placed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project’s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;directory.&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"codeSigningCertificate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./certs/certificate.pem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Metadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;related&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;process.&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyid"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;should&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;correspond&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;identifier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key.&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alg"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specifies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cryptographic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;algorithm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;used&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(e.g.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;RSA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;SHA&lt;/span&gt;&lt;span class="mi"&gt;-256&lt;/span&gt;&lt;span class="err"&gt;).&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"codeSigningMetadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"keyid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rsa-v1_5-sha256"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"requestHeaders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"expo-channel-name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"channel"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code signing fields secure your updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tip: If you run npx expo prebuild after setting the requestHeaders property, the necessary configuration will be automatically injected into both AndroidManifest.xml and Expo.plist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add Scripts to Upload Update Bundles&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "scripts": {
    "expo-publish-alt": "node ./scripts/publish.js",
    "expo-rollback-alt": "node ./scripts/rollback.js"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These scripts handle the uploading of new update bundles to your custom server. In this setup, while the publish script worked properly, the rollout (gradual update distribution) wasn’t implemented on the server side. After understanding channels and branches management, you may choose to migrate to EAS Update without relying on EAS Build if that better fits your workflow.&lt;/p&gt;

&lt;p&gt;💾 Setting up a custom Expo updates server gives you granular control over update distribution, code signing, and rollout strategies. By manually configuring both your server and your React Native app, you can tailor the OTA update process to your specific requirements. However, as you refine your approach, you might find that the channel and branch management capabilities provided by EAS Update offer a more streamlined solution—especially if you decide not to use EAS Build.&lt;/p&gt;




&lt;p&gt;📚 Additional resources:&lt;br&gt;
👉 Expo OTA Updates &lt;a href="https://docs.expo.dev/deploy/send-over-the-air-updates/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Expo EAS Update &lt;a href="https://docs.expo.dev/eas-update/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Secure your update bundles by following best practices for &lt;a href="https://docs.expo.dev/eas-update/code-signing/" rel="noopener noreferrer"&gt;Expo Code Signing for OTA Updates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Custom Expo Updates Server &lt;a href="https://github.com/expo/custom-expo-updates-server/tree/main" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Over-the-air (OTA) updates through Expo's EAS Update revolutionize mobile app development by enabling rapid  deployment of bug fixes, performance optimizations, and new features, bypassing the delays of traditional app store reviews. By following best practices, such as effective channel and branch management, secure code signing, and rigorous testing, you can mitigate OTA limitations and deliver a seamless, high-quality user experience.&lt;/p&gt;

&lt;p&gt;Happy Building! Great solutions power exceptional experiences. 🚀&lt;/p&gt;

</description>
      <category>ota</category>
      <category>reactnative</category>
      <category>mobile</category>
      <category>development</category>
    </item>
    <item>
      <title>React Native Under the Hood: How Your JS, iOS, and Android Code Run Together?</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Sun, 27 Apr 2025 06:39:25 +0000</pubDate>
      <link>https://dev.to/nour_abdou/react-native-under-the-hood-how-your-js-ios-and-android-code-run-together-3k2e</link>
      <guid>https://dev.to/nour_abdou/react-native-under-the-hood-how-your-js-ios-and-android-code-run-together-3k2e</guid>
      <description>&lt;p&gt;Ever wondered how React Native actually runs your code?&lt;br&gt;
When working with React Native, it's essential to understand how JavaScript, iOS, and Android handle code execution and compilation.&lt;/p&gt;

&lt;p&gt;Unlike native platforms that use compiled languages, JavaScript does not have a traditional build system but undergoes a different transformation process. You write JavaScript/TypeScript, but it controls native iOS and Android components. &lt;/p&gt;

&lt;p&gt;It's a multi-stage process involving transpilation, bundling, JavaScript execution, communication, and native rendering.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Flow
&lt;/h4&gt;

&lt;p&gt;1- Development: Write TS code.&lt;br&gt;
2- Build: TS -&amp;gt; JS (transpilation) -&amp;gt; JS Bundle (Metro).&lt;br&gt;
3- Launch: Native app shell starts, loads JS bundle into a JS Engine (Hermes/JSC).&lt;br&gt;
4- Execution: JS code runs, React determines UI structure.&lt;br&gt;
5- Rendering: React instructions are sent via Bridge/JSI to native View Managers, which create/update native UI elements (UIView, android.view.View).   &lt;br&gt;
6- Interaction: User interacts with native UI elements -&amp;gt; Events sent via Bridge/JSI back to JS -&amp;gt; JS event handlers run -&amp;gt; State updates -&amp;gt; UI potentially re-renders (back to step 5).&lt;br&gt;
7- Native APIs: JS calls Native Modules -&amp;gt; Bridge/JSI relays call to native code -&amp;gt; Native code executes platform API -&amp;gt; Result sent back via Bridge/JSI to JS.&lt;/p&gt;

&lt;p&gt;Let's break down the execution and compilation flow for each part.&lt;/p&gt;




&lt;h2&gt;
  
  
  JavaScript (The Brains 🧠)
&lt;/h2&gt;

&lt;p&gt;While JavaScript is typically an interpreted language, unlike natively compiled languages like Swift or Kotlin, React Native involves a form of "compilation" steps before your code actually runs on the device.&lt;br&gt;
But In case your application is written in TypeScript benefiting from static typing, interfaces, and other TS features, the first step is: &lt;/p&gt;

&lt;h3&gt;
  
  
  📌 TypeScript to JavaScript Transformation &lt;strong&gt;(Build Time)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Before your code can run, it needs to be converted into JavaScript, which is what React Native's runtime environment understands. The TS compiler (tsc) is responsible for this.&lt;/li&gt;
&lt;li&gt;During the build process (when you run npx react-native run-ios or run-android), tsc (often invoked implicitly by the Metro bundler) reads your .ts and .tsx files. It performs type checking and then removes all the TypeScript-specific syntax (like type annotations, interfaces, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Output: The output of this step is standard JavaScript code (.js) that is functionally equivalent to your TypeScript code, just without the type information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now&lt;/strong&gt;, Your JS logic is transpiled and bundled by Metro during the build Time. If using Hermes, it's further compiled to optimized bytecode. &lt;br&gt;
This final package runs within a dedicated JS environment on the device, communicating with the native side to control the app's UI and functionality: &lt;/p&gt;

&lt;h3&gt;
  
  
  📌 JavaScript Bundling &lt;strong&gt;(Build Time)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;React Native uses Metro, a specialized JavaScript bundler, to handle this. Metro performs two key tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transpilation: Due to evolving JavaScript (ECMAScript) standards and the use of JSX, your code needs to be transformed into a version that the target JavaScript engine (e.g., Hermes) can understand. 
Metro uses Babel under the hood for this; Babel rewrites modern JavaScript syntax and JSX into compatible code, guided by React Native's specific Babel preset to match the capabilities of the engine being used.&lt;/li&gt;
&lt;li&gt;Bundling: Metro bundles all your JavaScript files and dependencies into one (or a few) efficient JS files (bundles), optimized for loading at runtime (understandable for JS engine).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Output: The JS Bundle; This is typically a single .js file (e.g., index.bundle) containing all the application logic ready to be executed.   &lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Running the JavaScript &lt;strong&gt;(Runtime)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you build your React Native app, a Native "shell" application is created for both iOS (using Objective-C/Swift) and Android (using Java/Kotlin). This shell contains the necessary native code to host React Native.&lt;/p&gt;

&lt;h4&gt;
  
  
  Execution JS Engine (JavaScriptCore vs. Hermes):
&lt;/h4&gt;

&lt;p&gt;This native shell embeds a JS engine (a program that executes JS code). React Native can use different engines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JavaScriptCore (JSC): Historically common, it's the engine used by Safari. It's also available on Android but less used now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hermes: An open-source JavaScript engine optimized by Meta specifically for running React Native appsand It's often the default for new React Native projects on both platforms.&lt;br&gt;
A key advantage of Hermes is that during the app build phase, it pre-compiles the JavaScript bundle into bytecode. &lt;br&gt;
This bytecode format allows for significantly faster app startup times (Time To Interactive - TTI) and reduced memory usage compared to interpreting raw JS or using Just-In-Time (JIT) compilation on the device.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ So.. When you launch the app, the native shell starts the JS engine and loads the JS bundle created by Metro. Then, The JS engine starts executing your application's code, beginning with your entry point (usually index.js). React starts rendering your components in memory.&lt;/p&gt;




&lt;p&gt;We'll talk now about Communication &amp;amp; Native Modules and Native Components.&lt;/p&gt;

&lt;h2&gt;
  
  
  iOS (Swift/Objective-C - The Looks &amp;amp; Feel on Apple🍎)
&lt;/h2&gt;

&lt;p&gt;Unlike JavaScript, Swift and Objective-C are compiled languages. The iOS build system compiles source code (including the native parts of React Native itself and any native modules you add) into machine code before execution, ensuring optimized performance on Apple devices.&lt;/p&gt;

&lt;p&gt;React Native for iOS relies on Xcode's build system, which uses Clang compiler (for Objective-C) and LLVM toolchain (for Swift) to convert human-readable source code into an optimized binary specific to the iPhone/iPad processor (such as .app bundle).&lt;/p&gt;

&lt;p&gt;Here are the key steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source Compilation: Swift and Objective-C files are compiled into machine code using Clang/LLVM.&lt;/li&gt;
&lt;li&gt;Linking: All compiled code, system frameworks, and external libraries (from CocoaPods) are linked together.&lt;/li&gt;
&lt;li&gt;Signing: Apple requires apps to be signed with valid certificates and provisioning profiles before they can be run on a device.&lt;/li&gt;
&lt;li&gt;Packaging: The final binary (.ipa file) is generated, containing the app and its resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Result: This compiled code is packaged into the .app bundle that gets installed on the user's device. It runs directly on the hardware when the app starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android (Kotlin/Java - The Looks &amp;amp; Feel on Android 🤖)
&lt;/h2&gt;

&lt;p&gt;Similar to iOS (but a bit more layered process), Android uses a compiled build system, relying on Gradle, which automates the process of building, testing, and packaging an Android app.&lt;/p&gt;

&lt;p&gt;React Native for Android compiles Java/Kotlin source code into Dalvik Executable (DEX) format, which is optimized for execution by the Android Runtime (ART).&lt;/p&gt;

&lt;p&gt;Here are the key steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source Compilation: Java/Kotlin files are compiled into .class bytecode files using the javac (for Java) and kotlinc (for Kotlin) compilers.&lt;/li&gt;
&lt;li&gt;DEX Conversion: The compiled .class files (JVM Bytecode) are converted into .dex files (Dalvik Bytecode), optimized for the Android Runtime using the DEX compiler (d8).&lt;/li&gt;
&lt;li&gt;Resource Processing: XML layouts, images, and other assets are bundled.&lt;/li&gt;
&lt;li&gt;Linking: External libraries and dependencies (managed by Gradle) are linked.&lt;/li&gt;
&lt;li&gt;Signing: Android requires apps to be signed with a valid keystore file.&lt;/li&gt;
&lt;li&gt;Packaging: The final .apk or .aab file is generated for installation on devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ Result: This compiled/optimized code is packaged into an .apk or .aab file for distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Communication: The Bridge / JSI &lt;strong&gt;(Runtime)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is the core of how JavaScript interacts with the native platform. There are two main architectures:&lt;br&gt;
1- The Bridge (Older Architecture):&lt;br&gt;
The Bridge acts as a message broker between your JS code and the native iOS/Android platform.&lt;br&gt;
It asynchronously sends serialized data (commands, UI updates) from JS to Native.&lt;br&gt;
Then Native code executes these commands and sends results or user interaction events back to JS.&lt;br&gt;
But, Its Asynchronous nature can lead to latency, serialization/deserialization overhead ("Bridge Tax"), and potential bottlenecks if too many messages are sent. &lt;/p&gt;

&lt;p&gt;2- JavaScript Interface (JSI) (New Architecture - Fabric &amp;amp; TurboModules):&lt;br&gt;
React Native's new architecture replaces the asynchronous Bridge with the JavaScript Interface (JSI).&lt;br&gt;
JSI allows direct, synchronous calls between JavaScript and Native (via C++), eliminating serialization overhead.&lt;br&gt;
This powers Fabric (a faster UI rendering system) and TurboModules (faster, lazy-loaded native modules).&lt;br&gt;
The result is significantly improved performance, responsiveness, and better feature support.&lt;/p&gt;

&lt;p&gt;For more about these architectures, Checkout my Article about &lt;a href="https://dev.to/nour_abdou/how-react-native-works-internally-4o42#New%20Architecture's%20Improvements"&gt;How React Native works internally?&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Native Modules and Native Components (Runtime)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Native Modules Expose native platform APIs (like camera, geolocation, storage, Bluetooth, custom native code) to your JavaScript code.&lt;br&gt;
When your JS calls NativeModules.MyCamera.takePicture(), the JSI translates this into a call to the corresponding native Objective-C/Swift (iOS) or Java/Kotlin (Android) method. The native code executes, and the result is sent back to JS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Native Components (View Managers): These are the counterparts to React components like &lt;code&gt;&amp;lt;View&amp;gt;, &amp;lt;Text&amp;gt;, &amp;lt;Image&amp;gt;&lt;/code&gt;, etc.&lt;br&gt;
When React decides to render a &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt;, it doesn't create an HTML &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, but it sends instructions (via JSI) to the native side. &lt;br&gt;
  &lt;br&gt;
-&amp;gt; &lt;strong&gt;On iOS&lt;/strong&gt;, a native "View Manager" receives these instructions and creates/updates an actual native &lt;code&gt;UIView&lt;/code&gt;.&lt;br&gt;
-&amp;gt; &lt;strong&gt;On Android&lt;/strong&gt;, a native "View Manager" creates/updates an actual native &lt;code&gt;android.view.View&lt;/code&gt;.   &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that your UI looks and feels native because it is using native platform UI elements. The layout logic (like Flexbox) is calculated (often on a background thread) and then applied to these native views on the main UI thread.   &lt;/p&gt;




&lt;h3&gt;
  
  
  Running the application on the device
&lt;/h3&gt;

&lt;p&gt;Testing is an essential part of the mobile app development workflow. Unlike web applications, which can be tested directly in a browser, mobile apps require simulators (emulators in Android) or physical devices for testing. Simulators allow developers to run and debug apps in a controlled environment that mimics real-world device behavior.&lt;br&gt;
■ &lt;strong&gt;Android&lt;/strong&gt;&lt;br&gt;
You can interact with Android emulators using the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Studio AVD Manager: The built-in tool for managing Android emulators.
You can create, configure, and launch virtual devices here.&lt;/li&gt;
&lt;li&gt;Command Line (adb and emulator commands):&lt;/li&gt;
&lt;li&gt;emulator -list-avds—lists all available virtual devices.&lt;/li&gt;
&lt;li&gt;emulator @Pixel_6_API_34—launches a specific device.&lt;/li&gt;
&lt;li&gt;adb devices—lists running emulators and connected physical devices.
CLI tools such as Expo CLI or React Native Community CLI use these commands under the hood to provide a better developer experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;■ &lt;strong&gt;iOS&lt;/strong&gt;&lt;br&gt;
You can interact with iOS simulators via the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Xcode: Apple's built-in tool for running iOS apps on a simulated device. You can launch it via Xcode &amp;gt; Open Developer Tool &amp;gt; Simulator.&lt;/li&gt;
&lt;li&gt;Command Line (xcrun simctl commands):
➡️ xcrun simctl list—lists available simulators.
➡️ xcrun simctl boot "iPhone 15"—boots a specific simulator.
➡️ xcrun simctl shutdown all—shuts down all running simulators.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Happy building! &lt;br&gt;
Good Understanding leads to great experiences!  🚀&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Fixing App Installation Issues on Older Android Versions: Multiple APKs &amp; ABI Splitting</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Sat, 01 Feb 2025 18:43:27 +0000</pubDate>
      <link>https://dev.to/nour_abdou/solved-your-app-is-not-installable-on-android-api-less-than-30-18f7</link>
      <guid>https://dev.to/nour_abdou/solved-your-app-is-not-installable-on-android-api-less-than-30-18f7</guid>
      <description>&lt;p&gt;Are you facing issues with your app not installing on devices running Android versions lower than API 30? You're not alone! Many developers encounter problems when their app signing key is unexpectedly upgraded, causing compatibility issues with older Android versions. In this guide, we’ll walk you through a proven solution using Multiple APKs to ensure seamless distribution across different Android versions. Plus, we'll dive into ABI splitting to optimize performance and reduce APK size. Let’s fix your app installation issues and make your app more efficient than ever!&lt;/p&gt;




&lt;h1&gt;
  
  
  Problem statement
&lt;/h1&gt;

&lt;p&gt;If your app is failing to install on devices running Android versions below API 30, you're not alone. The issue arises from an unexpected upgrade of the app signing key, preventing the rollout of new releases with a minSdkVersion lower than 30. Fortunately, you don’t need to create a new app on Google Play—there’s a way to resolve this issue while keeping your existing app listing and user base intact.&lt;/p&gt;

&lt;h1&gt;
  
  
  Proposed solution
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Regarding Multiple APKs support&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To successfully roll out a new release without creating a new app, we need to upload both an app bundle and an APK signed with the legacy key in every release. Google Play will automatically generate APKs signed with the new key for devices running Android R* (API level 30) and above, while older Android versions (API level 29 and below) will continue receiving updates through the legacy APKs.&lt;/p&gt;

&lt;p&gt;This approach ensures seamless compatibility across different platform versions while maintaining a single app listing on Google Play.&lt;/p&gt;

&lt;h3&gt;
  
  
  How multiple APKs work
&lt;/h3&gt;

&lt;p&gt;Using multiple APKs on Google Play allows you to maintain a single app entry while delivering different APKs to different devices based on compatibility. This approach provides several key benefits:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Unified Product Details:&lt;/strong&gt; You manage only one set of product descriptions, images, and metadata—keeping your app listing consistent.&lt;br&gt;
✅ &lt;strong&gt;Consistent User Experience:&lt;/strong&gt; Users see only one version of your app on Google Play, avoiding confusion between different APK variants.&lt;br&gt;
✅ &lt;strong&gt;Unified Ratings &amp;amp; Reviews:&lt;/strong&gt; All user reviews apply to the same app listing, regardless of which APK version is downloaded.&lt;br&gt;
Seamless Updates: When a user upgrades their Android version, Google Play automatically provides the most compatible APK, ensuring a smooth transition.&lt;/p&gt;

&lt;p&gt;This method simplifies app management while ensuring optimal performance across a wide range of devices.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;API Level Considerations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The multiple APKs approach relies on the android:minSdkVersion and android:maxSdkVersion attributes in your app's manifest file. This allows you to serve different APKs based on a device’s Android version while maintaining a single app entry on Google Play.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can publish multiple APKs based on API levels, such as:&lt;/p&gt;

&lt;p&gt;APK 1: Supports API levels 16 - 19 (Android 4.1.x - 4.4.4), using only APIs available from API level 16 or lower.&lt;br&gt;
APK 2: Supports API levels 21 and above (Android 5.0+), using APIs available from API level 21 or lower.&lt;br&gt;
👉 To learn how to configure APKs for different API levels, refer to &lt;a href="https://developer.android.com/studio/build/build-variants#product-flavors" rel="noopener noreferrer"&gt;Configure Product Flavors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versioning Rules for Multiple APKs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an APK has a higher android:minSdkVersion, it must also have a higher android:versionCode to ensure proper updates through Google Play.&lt;/p&gt;

&lt;p&gt;This ensures that when a device receives a system update, Google Play can offer the user the most compatible version of your app—because updates are based on an increase in the app’s version code.&lt;/p&gt;

&lt;p&gt;For more details, refer to &lt;a href="https://developer.android.com/google/play/publishing/multiple-apks?hl=en#Rules" rel="noopener noreferrer"&gt;Rules for multiple APKs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avoid Using android:maxSdkVersion&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Avoid setting&lt;/strong&gt; android:maxSdkVersion unless absolutely necessary. Android is designed to maintain backward compatibility, so properly developed apps using public APIs will work with future Android versions.&lt;/p&gt;

&lt;p&gt;If you want to release a different APK for newer API levels, you don't need to specify maxSdkVersion—Google Play will automatically deliver the correct APK based on the minSdkVersion and versionCode.&lt;/p&gt;
&lt;h3&gt;
  
  
  Rules for multiple APKs
&lt;/h3&gt;

&lt;p&gt;Before publishing multiple APKs for your application, it’s essential to follow these rules to ensure compatibility and smooth updates:&lt;/p&gt;

&lt;p&gt;General Rules:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Same Package &amp;amp; Signature:&lt;/strong&gt; All APKs must have the same package name and be signed with the same key.&lt;br&gt;
✅ &lt;strong&gt;Unique Version Code:&lt;/strong&gt; Each APK must have a unique versionCode to differentiate it from other versions.&lt;br&gt;
✅ &lt;strong&gt;Distinct Configurations:&lt;/strong&gt; No two APKs should exactly match the same device configuration. Each APK should target a different device segment (e.g., API level, screen size, ABI).&lt;br&gt;
✅ &lt;strong&gt;Higher API Level = Higher Version Code:&lt;/strong&gt; An APK requiring a higher API level must have a higher versionCode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling Overlapping APKs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If multiple APKs differ only by API levels, or if they also use another distinguishing factor (e.g., screen size) but have overlapping filters, their versionCode values must increase in correlation with API levels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have an active APK for small - normal screen sizes with version code 0400, and you try to replace it with an APK targeting the same screen sizes but with version code 0300. This will cause an error, because users of the older APK would not be able to update the app due to the lower version code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 Google Play delivers app updates only if the new APK has a higher version code than the one installed on a device.&lt;/p&gt;

&lt;p&gt;📌 This rule ensures that if a device receives a system update, making it eligible for a higher API level, it will automatically receive the correct APK update with a higher version code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples of Version Code Rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To better understand how version codes should be assigned when using multiple APKs, consider the following scenarios:&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;API Levels Differ Only (Version Code Must Increase)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ If an APK for API levels 16+ (Android 4.1.x+) has a version code of 0400, then an APK for API levels 21+ (Android 5.0+) must have a version code of 0401 or higher.&lt;br&gt;
📌 This ensures that devices receiving a system update to API level 21 will also receive the new APK update.&lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;Overlapping Screen Sizes &amp;amp; API Levels (Version Code Must Increase)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ If one APK supports API level 16+ and small to large screens, while another supports API level 21+ and large to xlarge screens, the version codes must increase with API levels since large screens overlap.&lt;/p&gt;

&lt;p&gt;📌 Because both APKs support large screens, a large-screen device that upgrades to API level 21 should receive the correct APK update.&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;No Overlapping Filters (Version Code Doesn’t Need to Increase)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ If one APK supports API level 16+ with small to normal screens, and another supports API level 21+ with large to xlarge screens, then version codes do not need to increase.&lt;/p&gt;

&lt;p&gt;📌 Since there is no screen size overlap, no devices will transition between these APKs, so the version codes don’t need to be in sequential order.&lt;/p&gt;

&lt;p&gt;Following these versioning rules ensures seamless updates and avoids compatibility issues when rolling out multiple APKs. 🚀&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Assigning Version Codes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Each APK must have a unique versionCode to ensure proper ordering and flexibility for updates.&lt;/p&gt;

&lt;p&gt;Since Google Play uses android:versionCode to determine whether an update is available, you need to carefully structure version codes when publishing multiple APKs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordering Version Codes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 An APK requiring a higher API level must have a higher version code.&lt;/p&gt;

&lt;p&gt;For example, if you release two APKs for different API levels:&lt;/p&gt;

&lt;p&gt;The APK for API level 21+ must have a higher version code than the APK for API level 16+.&lt;br&gt;
This guarantees that devices updating to a higher Android version receive the appropriate APK update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using a Version Code Scheme&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To allow independent version updates for each APK (e.g., fixing a bug in one without updating others), use a structured versioning scheme:&lt;/p&gt;

&lt;p&gt;✅ Leave space between version codes to allow updates without affecting all APKs.&lt;br&gt;
✅ Embed the API level in the version code for clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;versionCode&lt;/span&gt; &lt;span class="mi"&gt;21012&lt;/span&gt;
&lt;span class="n"&gt;versionName&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;//21: API level (constant)&lt;/span&gt;
&lt;span class="c1"&gt;//012: version name (incremental)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;versionCode&lt;/span&gt; &lt;span class="mi"&gt;30012&lt;/span&gt;
&lt;span class="n"&gt;versionName&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;//30: API level (constant)&lt;/span&gt;
&lt;span class="c1"&gt;//012: version name (incramental)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that updates are managed efficiently while keeping the versioning system clear and maintainable. 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Split APKs Based on ABI&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why Split APKs Based on ABI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond supporting different API levels, splitting APKs based on ABI (Application Binary Interface) further optimizes performance and reduces app size.&lt;/p&gt;

&lt;p&gt;📌 Why does this matter?&lt;/p&gt;

&lt;p&gt;Android devices use different CPU architectures (armeabi-v7a, arm64-v8a, x86, x86_64).&lt;br&gt;
Including binaries for all architectures in a single APK increases its size unnecessarily.&lt;br&gt;
A device should only download the binaries it actually needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing ABI Splitting&lt;/strong&gt;&lt;br&gt;
We can extend the multiple APKs approach by also generating separate APKs for different ABIs.&lt;/p&gt;

&lt;p&gt;To enable ABI-based APK splitting, modify your build.gradle file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;splits&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;abi&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;armeabi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v7a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;arm64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v8a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;x86&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
            &lt;span class="n"&gt;universalApk&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// Prevents generating a universal APK&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;Benefits of ABI Splitting&lt;br&gt;
✅ Smaller APKs: Only the necessary binaries are included, reducing file size.&lt;br&gt;
✅ Optimized Performance: Devices install APKs optimized for their specific CPU architecture.&lt;br&gt;
✅ Faster Updates: Smaller file sizes mean faster downloads and installations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ABI-Based Version Code Strategy&lt;/strong&gt;&lt;br&gt;
Each APK must have a unique versionCode to ensure proper updates. To achieve this, we can encode API level, version name, and ABI identifiers into the version code, following a structured approach.&lt;/p&gt;

&lt;p&gt;Example Version Code Structure&lt;br&gt;
To maintain proper ordering while allowing independent updates, we structure the versionCode as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;AACBBB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;br&gt;
AA → API level (constant)&lt;br&gt;
BBB → Version name (incremental)&lt;br&gt;
C → ABI identifier&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;versionCode&lt;/span&gt; &lt;span class="mi"&gt;210112&lt;/span&gt;
&lt;span class="n"&gt;versionName&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// 21: API level (constant)&lt;/span&gt;
&lt;span class="c1"&gt;// 012: Version name (incremental)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;versionCode&lt;/span&gt; &lt;span class="mi"&gt;300112&lt;/span&gt;
&lt;span class="n"&gt;versionName&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// 30: API level (constant)&lt;/span&gt;
&lt;span class="c1"&gt;// 012: Version name (incremental)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify your build.gradle to implement this structured versioning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;applicationVariants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="n"&gt;abiVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ABI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;armeabi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v7a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;abiVersion&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;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ABI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;arm64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v8a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;abiVersion&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;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ABI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;x86&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;abiVersion&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;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ABI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;abiVersion&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="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;versionCodeOverride&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;defaultConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;versionCode&lt;/span&gt; &lt;span class="n"&gt;abiVersion&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&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;How this works:&lt;/p&gt;

&lt;p&gt;The first two digits (AA) represent the API level.&lt;br&gt;
The next last three digits (BBB) track the app version.&lt;br&gt;
The third (C) uniquely identifies the ABI:&lt;br&gt;
1 → armeabi-v7a&lt;br&gt;
2 → arm64-v8a&lt;br&gt;
3 → x86&lt;br&gt;
4 → x86_64&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API Level&lt;/th&gt;
&lt;th&gt;Version Name&lt;/th&gt;
&lt;th&gt;ABI&lt;/th&gt;
&lt;th&gt;Final Version Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;0.1.2&lt;/td&gt;
&lt;td&gt;armeabi-v7a&lt;/td&gt;
&lt;td&gt;&lt;code&gt;211112&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;0.1.2&lt;/td&gt;
&lt;td&gt;arm64-v8a&lt;/td&gt;
&lt;td&gt;&lt;code&gt;212112&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;0.1.2&lt;/td&gt;
&lt;td&gt;x86&lt;/td&gt;
&lt;td&gt;&lt;code&gt;213112&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;0.1.2&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;&lt;code&gt;214112&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Using this structured approach ensures:&lt;br&gt;
✅ Proper versioning for updates&lt;br&gt;
✅ Consistent ordering of APKs&lt;br&gt;
✅ Easy maintenance of separate APKs for API levels &amp;amp; ABIs&lt;/p&gt;

&lt;p&gt;This method provides a future-proof way to manage multiple APKs efficiently! 🚀&lt;/p&gt;




&lt;h1&gt;
  
  
  📚 References
&lt;/h1&gt;

&lt;p&gt;For you to dive deeper into the technical details of multiple APK support, versioning strategies, and ABI-based APK splitting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.android.com/google/play/publishing/multiple-apks" rel="noopener noreferrer"&gt;Google Play Multiple APK Support&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.android.com/studio/publish/versioning" rel="noopener noreferrer"&gt;Managing Version Codes in Android&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.android.com/studio/build/configure-apk-splits" rel="noopener noreferrer"&gt;Android Splitting APKs by ABI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://support.google.com/googleplay/android-developer/answer/7384423" rel="noopener noreferrer"&gt;Google Play App Signing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.android.com/build/shrink-code#split-apks" rel="noopener noreferrer"&gt;Gradle Configuration for APK Splitting&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Solving - Great solutions lead to great experiences! ! 🚀&lt;/p&gt;

</description>
      <category>android</category>
      <category>googleplay</category>
      <category>apk</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How React Native works internally?</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Wed, 07 Dec 2022 07:17:46 +0000</pubDate>
      <link>https://dev.to/nour_abdou/how-react-native-works-internally-4o42</link>
      <guid>https://dev.to/nour_abdou/how-react-native-works-internally-4o42</guid>
      <description>&lt;p&gt;You may built some applications using React Native or you've just started learning it!&lt;br&gt;
Despite it is not a requirement to be effective with React Native, but for better developing experience, you should know the mechanics of React Native and what exactly happens in the low level code; that is what you are about to read here. &lt;/p&gt;




&lt;h2&gt;
  
  
  Table Of Contents:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
Old React Native

&lt;ul&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Threading Model&lt;/li&gt;
&lt;li&gt;Working process&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Old Architecture's Issues&lt;/li&gt;
&lt;li&gt;New Architecture's Improvements&lt;/li&gt;
&lt;li&gt;
New React Native started with RN 0.68

&lt;ul&gt;
&lt;li&gt;Fabric Renderer&lt;/li&gt;
&lt;li&gt;Threading Model&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Introduction &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;React Native has been successfully adopted by hundreds of businesses worldwide, including Uber, Discord, Microsoft, and Facebook, and is used across a whole range of industries.&lt;/p&gt;

&lt;p&gt;It is a JavaScript-based mobile app framework that allows you to build natively-rendered mobile apps for iOS and Android, using the same codebase.&lt;/p&gt;

&lt;p&gt;Since Java and Objective C are strongly typed languages while Javascript is not, React Native can be considered as a set of components, where each component represents the corresponding native views and components. &lt;/p&gt;

&lt;p&gt;For example, a native TextInput will have a corresponding RN component which can be directly imported into the JS code and used like any other React component. Hence, the developer will be writing the code just like for any other React web app but the output will be a native application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Old React Native architecture &amp;amp; Threading Model &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are three main parts:&lt;/p&gt;

&lt;h4&gt;
  
  
  Native side
&lt;/h4&gt;

&lt;p&gt;Most of the native code in case of &lt;code&gt;iOS&lt;/code&gt; is written in &lt;code&gt;Objective C&lt;/code&gt; or &lt;code&gt;Swift&lt;/code&gt;, while in the case of &lt;code&gt;Android&lt;/code&gt; it is written in &lt;code&gt;Java&lt;/code&gt; or &lt;code&gt;Kotlin&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Javascript side (JS VM)
&lt;/h4&gt;

&lt;p&gt;The JS Virtual Machine that runs all our JavaScript code. On iOS/Android simulators and devices, React Native uses JavaScriptCore, which is the JavaScript engine that powers Safari. JavaScriptCore is an open source JavaScript engine originally built for WebKit.&lt;/p&gt;

&lt;p&gt;In case of debugging mode, the JavaScript code runs within &lt;strong&gt;Chrome&lt;/strong&gt; itself (instead of the JavaScriptCore on the device) and communicates with native code via &lt;strong&gt;WebSocket&lt;/strong&gt;. Here, it will use the V8 engine. This allows us to see a lot of information on the Chrome debugging tools like network requests, console logs, etc. &lt;/p&gt;

&lt;h4&gt;
  
  
  React Native Bridge
&lt;/h4&gt;

&lt;p&gt;React Native bridge is a C++/Java Component which is responsible for communication between the Native and Javascript thread. Like a custom protocol used for message passing. It can be imagined as a bus where the producer layer sent some data for the consumer layer. The consumer could read the data, deserialize it and execute the required operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jBh0azaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gaxpcaq5faz4gqiy5a78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jBh0azaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gaxpcaq5faz4gqiy5a78.png" alt="react native bridge" width="880" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Source:&lt;code&gt;Hackernoon&lt;/code&gt;
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Threading Model &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Fz6Epyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qn0msoiq1zo0h5wl5f77.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Fz6Epyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qn0msoiq1zo0h5wl5f77.jpeg" alt="Threading Model" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a RN application is launched, it spawns up the following threading queues:&lt;/p&gt;

&lt;h4&gt;
  
  
  UI Thread/Main thread (Native Queue)
&lt;/h4&gt;

&lt;p&gt;This is the place where the native code is executed. It loads the app and starts the JS thread to execute the Javascript code. &lt;br&gt;
All the native modules lie in the startup, which means they will always be bundled if the user wants to access them. In other words, the native thread listens to the UI events like &lt;code&gt;'press'&lt;/code&gt;, &lt;code&gt;'touch'&lt;/code&gt;, etc. These events are then passed to the JS thread via the RN Bridge.&lt;/p&gt;

&lt;h4&gt;
  
  
  Shadow Thread
&lt;/h4&gt;

&lt;p&gt;It is the place where the layout of your application is calculated using React library. This cross-platform framework handles this task with the help of Facebook’s own layout engine called Yoga. It transforms flexbox layouts, calculates them and sends them to the app’s interface. It is basically like a mathematical engine which finally decides on how to compute the view positions, to be passed back to the main thread to render the view.&lt;/p&gt;

&lt;h4&gt;
  
  
  JavaScript thread (JS Queue)
&lt;/h4&gt;

&lt;p&gt;This is the place where main bundled JS thread runs; where the entire JavaScript code is placed and compiled. The JS thread runs all the business logic, i.e., the code we write in React Native. And when the app is bundled for production, the &lt;code&gt;JavaScriptCore&lt;/code&gt; runs the bundle when the user starts the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working process &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In most cases, a developer would write the entire React Native application in Javascript.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At the first start of the app, the main thread starts execution and starts loading JS bundles.&lt;/li&gt;
&lt;li&gt;The JS thread sends the information on what needs to be rendered onto the screen. &lt;/li&gt;
&lt;li&gt;Then the Shadow thread uses this information to compute the layouts.&lt;/li&gt;
&lt;li&gt;And then sends layout parameters/objects to the main(UI) thread.&lt;/li&gt;
&lt;li&gt;Since only the main thread is able to render something on the screen, shadow thread should send generated layout to the main thread, and only then UI renders.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Old Architecture's Issues​ &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The Old Architecture used to work by serializing all the data that has to be passed from the JS layer to the native layer using The Bridge. &lt;/p&gt;

&lt;p&gt;The Bridge had some limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It was asynchronous:&lt;/strong&gt; one layer submitted the data to the bridge and asynchronously "waited" for the other layer to process them, even when this was not really necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It was single threaded:&lt;/strong&gt; JS used to work on a single thread, therefore the computation that happened in that world had to be performed on that single thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It imposed extra overheads:&lt;/strong&gt; everytime one layer had to use the other one, it had to serialize some data. The other layer had to deserialize them. The chosen format was JSON, for its simplicity and human-readability, but despite being lightweight, it was a cost to pay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Say an image file converted into base64 string!!!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  New Architecture's Improvements &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The New Architecture eliminate the bridge and let the UI be controlled directly from the JavaScript Interface (JSI) using native code. The JSI is an interface that allows a JavaScript object to hold a reference to a C++ and viceversa.&lt;/p&gt;

&lt;p&gt;This idea allowed to unlock several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous execution:&lt;/strong&gt; it is now possibile to execute synchronously those functions that should not have been asynchronous in the first place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency:&lt;/strong&gt; it is possible from JavaScript to invoke functions that are executed on different thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lower overhead:&lt;/strong&gt; there are no serialization taxes to pay, since the New Architecture don't have to serialize/deserialize the data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code sharing:&lt;/strong&gt; by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type safety:&lt;/strong&gt; to make sure that JS can properly invoke methods on C++ objects and viceversa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  New React Native architecture &amp;amp; Threading Model &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fabric Renderer &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;RN Fabric allows the UI thread (where UI is drawn) to be in sync with the JS thread (where the UI is programmed). In other words, it lets React talk to each platform and manage its host view instances!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--neZfR1HP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nb13ffgvrs62kg0qn6g1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--neZfR1HP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nb13ffgvrs62kg0qn6g1.jpg" alt="render pipeline" width="880" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The render pipeline can be broken into three general phases:&lt;/p&gt;

&lt;h4&gt;
  
  
  Render
&lt;/h4&gt;

&lt;p&gt;React executes product logic which creates a React Element Trees in JavaScript; each element is a JS object that describes what should appear on the screen, and includes props, styles, and children.&lt;br&gt;
From this tree, the renderer creates a React Shadow Tree in C++; which consists of React Shadow Nodes; each node is an object that represents a React Host Component to be mounted, and contains props that originate from JavaScript. They also contain layout information (x, y, width, height). &lt;/p&gt;

&lt;h4&gt;
  
  
  Commit
&lt;/h4&gt;

&lt;p&gt;After a React Shadow Tree is fully created, the renderer triggers a commit. This promotes both the React Element Tree and the newly created React Shadow Tree as the “next tree” to be mounted. This also schedules calculation of its layout information.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mount
&lt;/h4&gt;

&lt;p&gt;The React Shadow Tree, now with the results of layout calculation, is transformed into a Host View Tree.&lt;br&gt;
&lt;strong&gt;The host&lt;/strong&gt; &lt;a&gt;&lt;/a&gt; here represent the platform (e.g. Android, iOS). On Android, the host views are instances of android.view.ViewGroup, android.widget.TextView, etc. which are the building blocks of the host view tree. The size and location of each host view are based on LayoutMetrics calculated with Yoga, and the style and content of each host view are based on information from the React Shadow Tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QCV3Aua0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr9h5ttlbez1fuylf8t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QCV3Aua0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr9h5ttlbez1fuylf8t6.png" alt="render flow" width="880" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Threading Model &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;React Native renderer is designed to be thread safe. Every update in React creates or clones new objects in the renderer instead of updating data structures. This allows the framework to expose thread safe and synchronous APIs to React.&lt;/p&gt;

&lt;p&gt;The renderer uses three different threads:&lt;/p&gt;

&lt;h4&gt;
  
  
  UI Thread/Main thread
&lt;/h4&gt;

&lt;p&gt;The only thread that can manipulate host views.&lt;/p&gt;

&lt;h4&gt;
  
  
  JavaScript thread
&lt;/h4&gt;

&lt;p&gt;This is where React’s render phase is executed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Background thread
&lt;/h4&gt;

&lt;p&gt;Thread dedicated to layout.&lt;/p&gt;




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

&lt;p&gt;In this article we had conceptual overview of how React Native's internals work. From the old school to the current one, which brings an improvement in startup time, and developer experience, with improved interoperability between all threads.&lt;/p&gt;




&lt;h2&gt;
  
  
  References &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RN Guide. &lt;em&gt;reactnative.guide&lt;/em&gt;. Available from: &lt;a href="https://www.reactnative.guide"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How RN works?. &lt;em&gt;geeksforgeeks.org&lt;/em&gt;. Available from: &lt;a href="https://www.geeksforgeeks.org/react-native-works/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RN Architecture. &lt;em&gt;reactnative.dev&lt;/em&gt;. Available from: &lt;a href="https://reactnative.dev/architecture/overview"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Why A New Architecture?. &lt;em&gt;reactnative.dev&lt;/em&gt;. Available from &lt;a href="https://reactnative.dev/docs/the-new-architecture/why"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Express + Typescript + Mongoose boilerplate</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Sat, 03 Dec 2022 19:22:27 +0000</pubDate>
      <link>https://dev.to/nour_abdou/express-typescript-mongoose-boilerplate-2omp</link>
      <guid>https://dev.to/nour_abdou/express-typescript-mongoose-boilerplate-2omp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Build REST API with Express + Typescript + Mongoose boilerplate&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🏛 &lt;strong&gt;simple starter for newbies.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⚛️ My main goal is a simple and easy starter for new learners. I like you to be focused on the correct learning path and not spending hours in choosing the right project structure.&lt;/p&gt;

&lt;p&gt;✨ Features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beautiful Code as simple as possible.&lt;/li&gt;
&lt;li&gt;Clear Structure inspired by MVC Model.&lt;/li&gt;
&lt;li&gt;Local4ization implemention.&lt;/li&gt;
&lt;li&gt;Authorization CRUD example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📎 Available on Github: &lt;a href="https://github.com/NourAliAbdou/express-typescript-mongoose-boilerplate" rel="noopener noreferrer"&gt;express-typescript-mongoose-boilerplate&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Table of Content&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction

&lt;ul&gt;
&lt;li&gt;Backend development&lt;/li&gt;
&lt;li&gt;About API&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Express + Typescript + Mongoose boilerplate

&lt;ul&gt;
&lt;li&gt;About NodeJS&lt;/li&gt;
&lt;li&gt;ExpressJS&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Localization with I18n&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;You will know a bit about backend development frameworks and how to do so using ExpressJS &amp;amp; MongoDB with typescript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend development
&lt;/h3&gt;

&lt;p&gt;Any app or web service has two broad parts: the frontend (client side) and the backend (server side).&lt;/p&gt;

&lt;p&gt;The backend development is the part that you can’t “see”. It is the internal work including stuff like the server, the database, etc.&lt;/p&gt;

&lt;p&gt;Before dive in the backend dev tools, there are things you should be comfortable with, such as: Networks, Internet, Databases, Computer server.&lt;br&gt;
A networks is a collection of connected devices and computers; The Internet is the network of all networks; the database is where we store data in a well defined, accessible way and it has many types.&lt;br&gt;
Server is a computer program or device that provides a service to another computer program and its user/client.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tools used in backend development
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;scripting languages: PHP, Javascript, Ruby, etc.&lt;/li&gt;
&lt;li&gt;programming languages: python, java, etc.&lt;/li&gt;
&lt;li&gt;frameworks: NodeJS, Laravel, Django, flask, etc. &lt;/li&gt;
&lt;li&gt;databases: MongoDB, MySQL, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  About API
&lt;/h3&gt;

&lt;p&gt;(Application Programming Interface)&lt;br&gt;
An API is a set of programming code that enables data transmission between one software product and another. It also contains the terms of this data exchange The API defines endpoints, and valid request and response formats. &lt;/p&gt;

&lt;h4&gt;
  
  
  Types
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Open APIs
&lt;/h5&gt;

&lt;p&gt;Open APIs, also known as external or public APIs, are available to developers and other users with minimal restrictions. They may require registration, and use of an API key, or may be completely open.&lt;/p&gt;

&lt;h5&gt;
  
  
  Internal APIs
&lt;/h5&gt;

&lt;p&gt;Internal APIs are designed to be hidden from external users. They are used within a company to share resources. They allow different teams or sections of a business to consume each other’s tools, data and programs.&lt;/p&gt;

&lt;h5&gt;
  
  
  Partner APIs
&lt;/h5&gt;

&lt;p&gt;Partner APIs are technically similar to open APIs, but they feature restricted access, often controlled through a third-party API gateway.&lt;/p&gt;

&lt;h4&gt;
  
  
  API specifications/protocols
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Remote Procedure Call (RPC)
&lt;/h5&gt;

&lt;p&gt;This protocol specifies the interaction between applications based on the client-server architecture.&lt;/p&gt;

&lt;h5&gt;
  
  
  Service Object Access Protocol (SOAP)
&lt;/h5&gt;

&lt;p&gt;SOAP is a lightweight protocol for exchanging structured information in a decentralized, distributed environment. It  is mostly used with enterprise web-based software to ensure the high security of transmitted data. &lt;/p&gt;

&lt;h5&gt;
  
  
  Representational State Transfer (REST)
&lt;/h5&gt;

&lt;p&gt;The term REST was introduced by computer scientist Roy Fielding in a dissertation in 2000. Unlike SOAP, which is a protocol, REST is a software architectural style with six constraints for building applications that work over HTTP, often web services. &lt;br&gt;
REST is considered a simpler alternative to SOAP, which many developers find difficult to use because it requires writing a lot of code to complete every task and following the XML structure for every message sent. REST follows another logic since it makes data available as resources. Each resource is represented by a unique URL, and one can request this resource by providing its URL.&lt;/p&gt;

&lt;h5&gt;
  
  
  gRPC
&lt;/h5&gt;

&lt;p&gt;gRPC is an open-source universal API framework. With gRPC, the client application can directly call methods from a server application located on a different computer as if it was a local object. This makes it easier to create distributed services and applications.&lt;/p&gt;

&lt;h5&gt;
  
  
  GraphQL
&lt;/h5&gt;

&lt;p&gt;The need for faster feature development, more efficient data loading due to increased mobile adoption, and a multitude of clients, made the developers look for other approaches to software architecture. GraphQL, initially created by Facebook in 2012 for internal use, is the new REST with organizations like Shopify, Yelp, GitHub and Coursera using it to build APIs. &lt;br&gt;
GraphQL is a query language for APIs. It allows the client to detail the exact data it needs and simplifies data aggregation from multiple sources, so the developer can use one API call to request all needed data. Another special feature of GraphQL is that it uses a type system to describe data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Express + Typescript + Mongoose boilerplate
&lt;/h2&gt;

&lt;p&gt;simple starter for newbies.&lt;/p&gt;

&lt;p&gt;My main goal with this project is a simple and easy starter for new learners. I like you to be focused on the correct learning path and not spending hours in choosing the right project structure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beautiful Code as simple as possible.&lt;/li&gt;
&lt;li&gt;Clear Structure inspired by MVC Model.&lt;/li&gt;
&lt;li&gt;Localization implemention.&lt;/li&gt;
&lt;li&gt;Authorization CRUD example.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;project structure&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;src\&lt;br&gt;
    |--mvc&lt;br&gt;&lt;br&gt;
        |--models\              # Mongoose models (data layer)&lt;br&gt;
        |--routes\              # Views routes&lt;br&gt;
        |--controllers\         # Route controllers (controller layer)&lt;br&gt;
        |--middlewares\         # Custom express middlewares&lt;br&gt;
    |--helpers\             # Utility functions&lt;br&gt;
    |--app.js               # Express app&lt;br&gt;
    |--init\                # Init Express app&lt;br&gt;
        |--locales\             # translation maps&lt;br&gt;
        |--db.ts                # Init DB Connection&lt;br&gt;
        |--localize.ts          # Init localization&lt;br&gt;
        |--routes.ts            # Init Routes&lt;br&gt;
        |--thApp.ts             # Express app&lt;br&gt;
|--index.ts             # App entry point&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  about NodeJS&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Node.js is an open source, cross-platform runtime environment for developing server-side and networking applications, built on Google Chrome's JavaScript Engine (V8 Engine). Node.js was developed by Ryan Dahl in 2009.&lt;/p&gt;

&lt;h3&gt;
  
  
  about Express
&lt;/h3&gt;

&lt;p&gt;Express is a minimal and flexible Node.js web application framework that provides a robust set of features to develop web and mobile applications. It facilitates the rapid development of Node based Web applications. &lt;br&gt;
Some of the core features of Express framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows to set up middlewares to respond to HTTP Requests.&lt;/li&gt;
&lt;li&gt;Defines a routing table which is used to perform different * * actions based on HTTP Method and URL.&lt;/li&gt;
&lt;li&gt;Allows to dynamically render HTML Pages based on passing arguments to templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More Info about Express Available from &lt;a href="https://www.tutorialspoint.com/nodejs/nodejs_express_framework.htm" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  about MongoDB
&lt;/h3&gt;

&lt;p&gt;MongoDB is a document database designed for ease of application development and scaling.&lt;/p&gt;

&lt;p&gt;MongoDB stores data as JSON documents.&lt;/p&gt;

&lt;p&gt;The document data model maps naturally to objects in application code, making it simple for developers to learn and use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwebimages.mongodb.com%2F_com_assets%2Fcms%2Fku45cnpkie614gf6u-JSON_Document.png%3Fauto%3Dformat%25252Ccompress" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwebimages.mongodb.com%2F_com_assets%2Fcms%2Fku45cnpkie614gf6u-JSON_Document.png%3Fauto%3Dformat%25252Ccompress" alt="mongo document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fields in a JSON document can vary from document to document. Compare that to a traditional relational database table, where adding a field means adding a column to the database table itself and therefore to every record in the database.&lt;/p&gt;

&lt;p&gt;Documents can be nested to express hierarchical relationships and to store structures such as arrays.&lt;/p&gt;

&lt;p&gt;Then&lt;/p&gt;

&lt;p&gt;A collection is a group of documents.&lt;/p&gt;

&lt;p&gt;If you are familiar with relational databases, you can think of a collection as a table. But collections in MongoDB are far more flexible. Collections do not enforce a schema, and documents in the same collection can have different fields.&lt;/p&gt;

&lt;p&gt;creating a db in mongoose: &lt;a href="https://www.mongodb.com/basics/create-database" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Localization with I18n
&lt;/h3&gt;

&lt;p&gt;Most frameworks leave it to you how translations are being loaded. You are responsible to detect the user language, to load the translations and push them into the framework.&lt;/p&gt;

&lt;p&gt;I used &lt;code&gt;i18next&lt;/code&gt; which is an internationalization-framework written in and for JavaScript. &lt;br&gt;
with &lt;code&gt;i18next-http-middleware&lt;/code&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic Concept Of Back-end Web Development. Available from: &lt;a href="https://medium.com/@rexsteroxy22/basic-concept-of-back-end-web-development-43d9d991c056" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Types of APIs. Available from: &lt;a href="https://stoplight.io/api-types" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;What is an API. Available from: &lt;a href="https://www.altexsoft.com/blog/engineering/what-is-api-definition-types-specifications-documentation/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.js tutorial. Available from: &lt;a href="https://www.tutorialspoint.com/nodejs" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MongoDB. Available from: &lt;a href="https://www.mongodb.com" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Learning ..&lt;br&gt;
Happy Building ...&lt;/p&gt;

</description>
      <category>boilerplate</category>
      <category>express</category>
      <category>typescript</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>How to implement CRUD Concept in daily life?</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Tue, 15 Nov 2022 13:26:58 +0000</pubDate>
      <link>https://dev.to/nour_abdou/how-to-implement-crud-concept-in-daily-life-2lp6</link>
      <guid>https://dev.to/nour_abdou/how-to-implement-crud-concept-in-daily-life-2lp6</guid>
      <description>&lt;p&gt;One way to stay productive is to cultivate the mindset that makes the best use of your resources, your time, your energy, your efforts and connecting your knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CRUD&lt;/strong&gt; refers to the four basic operations a software application should be able to perform – Create, Read, Update, and Delete; create data, have access to the data in the UI by reading the data, update or edit the data, and delete the data. CRUD apps consist of 3 parts: an API, a database, and a user interface (UI).&lt;/p&gt;

&lt;p&gt;Assume that the data is your ideas or tasks, with crud:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create (a task/idea)&lt;/li&gt;
&lt;li&gt;Read (view/read the task/idea)&lt;/li&gt;
&lt;li&gt;Update (the task/idea)&lt;/li&gt;
&lt;li&gt;Delete (delete the task/idea)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Create (a task/idea)
&lt;/h3&gt;

&lt;p&gt;write down your thought as it pop up to the UI (your mind): a topic to think about deeply, projects ideas, business ideas, monthly/yearly goals or references to a specific to-do list, job applications, useful links, and so on. &lt;/p&gt;

&lt;p&gt;Use a notebook for quick ideas/tasks or the Quick Notes on your Mac, that's designed to be a quicker way to jot down things on your Mac without having to go in and out of the main Notes app (keep it in local storage until you call the api to create on database later).&lt;/p&gt;

&lt;p&gt;In order to have everything stored and reachable easily (DB), use Notion, ClickUp or any other tool you prefer and use a suitable template which makes it a lot easier to store and sort everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read (view/read the task/idea)
&lt;/h3&gt;

&lt;p&gt;categories your notes to tasks, business idea, projects, to-dos, and so on. So you can review your notes weekly. Or schedule a session to review your ideas in deep.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update (the task/idea)
&lt;/h3&gt;

&lt;p&gt;During your review sessions, you may change priorities if needed, or add description or a link to a note or a thought.&lt;br&gt;
or even change note category, like from business idea to a to-do list 😍.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete (delete the task/idea)
&lt;/h3&gt;

&lt;p&gt;After thinking deeply in a though or doing research on a business idea, you may find it worthless!&lt;br&gt;
So here delete it permanently or just archive it into the forgotten land.&lt;/p&gt;

&lt;p&gt;Simple, right? 😌&lt;/p&gt;




&lt;p&gt;So Here we go, a productive mindset inspired by CRUD operations which are so fundamental in our tech world.&lt;/p&gt;




&lt;p&gt;Thanks for reading 😃&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>mindset</category>
      <category>lifeofprogrammer</category>
    </item>
    <item>
      <title>Book recommendation: Clean Code</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Sun, 13 Nov 2022 20:13:54 +0000</pubDate>
      <link>https://dev.to/nour_abdou/book-recommendation-clean-code-kji</link>
      <guid>https://dev.to/nour_abdou/book-recommendation-clean-code-kji</guid>
      <description>&lt;h2&gt;
  
  
  Clean Code: A Handbook of Agile Software Craftsmanship
&lt;/h2&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t4tLYCE8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xrgx56s2gfpnrfo9s0a5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t4tLYCE8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xrgx56s2gfpnrfo9s0a5.jpeg" alt="" width="880" height="1085"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Writing clean code is what you must do in order to call yourself a professional. There is no reasonable excuse for doing anything less than your best.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Even though I read the &lt;strong&gt;Clean Code&lt;/strong&gt; book a while ago and there are a lot of reviews already available, I couldn't resist writing about it a bit.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Clean Code&lt;/strong&gt; book makes you feel like why didn’t you come across it before. It's all about writing high quality code, and how to judge the quality of code. With magic points, Encouraging the reader to write natural language code which is understandable by human brain smoothly, with any syntax of any language you use in you project.&lt;/p&gt;

&lt;p&gt;As you can't see the right thing without knowing the wrong, the book presents a code that is ugly, hard to read, understand and maintain, then Uncle Bob led the way step by step to refactor that code and transform it into clean, readable, understandable and maintainable code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code
&lt;/h2&gt;

&lt;p&gt;No doubt about that messy code can work as long as it does what it's intended to do without logical errors. But this broken windows mentality leads to waste countless hours and resources to update or modify the code.&lt;/p&gt;

&lt;p&gt;However, the book gathers thoughts on good code and its various attributes from a number innovators and authors such as Kent Beck, Bjarne Stroustrup, Dave Thomas, etc.&lt;/p&gt;

&lt;p&gt;To make the code easy to read, it gives you the golden advice of using intention-revealing names. emphasize to NOT use member prefix such as _ or m_.&lt;/p&gt;

&lt;p&gt;And for functions and methods, they should be small and cohesive. It also suggests using single level of abstraction to facilitate reading code from top to bottom.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Single level of abstraction Principle (SLAP); it means that every function / method in your codebase should deal with just one level of abstraction and do one thing, just like &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt; mentioned in my previous article about &lt;a href="https://dev.to/nour_abdou/sd-solid-principles-for-react-react-native-2910"&gt;SOLID Principles&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to explain yourself, you should write good comments that focus on intent and is not redundant and misleading.&lt;/p&gt;

&lt;p&gt;Discussing error handling, it encourages use of exceptions rather than return codes or error codes. It prohibits use of checked exceptions as it violates open/closed principle (one of SOLID principles, read &lt;a href="https://dev.to/nour_abdou/sd-solid-principles-for-react-react-native-2910"&gt;here&lt;/a&gt;). It also discourages returning or passing null.&lt;/p&gt;

&lt;p&gt;It pays great attention to unit testing and test-driven development (TDD) which is one of the main phases of the development cycle.&lt;/p&gt;




&lt;p&gt;Fun thing that the book includes a lot of blank pages with &lt;code&gt;"This page intentionally left blank"&lt;/code&gt;; they are after each chapter; to make you stop and think little more longer.&lt;/p&gt;




&lt;p&gt;Annoying thing for me that the book contains large number of code examples (that I skip sometimes 😅🥹), which is wonderful for sure to clarify rules and advices and so on.&lt;/p&gt;




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

&lt;p&gt;It's a must-read book for programmers, some of the outcomes of reading it, the ability to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write good code and clean bad code.&lt;/li&gt;
&lt;li&gt;Differentiate between good and bad code.&lt;/li&gt;
&lt;li&gt;Increase your code readability.&lt;/li&gt;
&lt;li&gt;Build reusable entities.&lt;/li&gt;
&lt;li&gt;Get used to explain yourself by good comments.&lt;/li&gt;
&lt;li&gt;Build elegant functions and components.&lt;/li&gt;
&lt;li&gt;fit error handling to your code logic.&lt;/li&gt;
&lt;li&gt;Unit test for a shorter dev cycle.&lt;/li&gt;
&lt;li&gt;Practice TTD.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading! 😄&lt;/p&gt;

</description>
      <category>agile</category>
      <category>books</category>
      <category>softwaredevelopment</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>SE SOLID Principles For React/ React Native</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Sat, 12 Nov 2022 11:16:39 +0000</pubDate>
      <link>https://dev.to/nour_abdou/sd-solid-principles-for-react-react-native-2910</link>
      <guid>https://dev.to/nour_abdou/sd-solid-principles-for-react-react-native-2910</guid>
      <description>&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Clean Architecture = Debt-free software.
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;Table of content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;SOLID principles&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The best practices and good software design principles emerge and conceptualize to avoid repeating mistakes amap, and SOLID is unquestionably one of the more influential ones. &lt;/p&gt;

&lt;h4&gt;
  
  
  The tell-tale signs of poor architecture
&lt;/h4&gt;

&lt;p&gt;The design of many software applications begins as a vital image in the minds of its designers. At this stage it is clean and elegant.&lt;br&gt;
However, there are four primary symptoms that tell us that our designs are rotting: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rigidity&lt;/strong&gt;; the tendency for software to be difficult to change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragility&lt;/strong&gt;; the tendency of the software to break in many places every time it is changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immobility&lt;/strong&gt;; the inability to reuse software from other projects or from parts of the same project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Viscosity&lt;/strong&gt;; comes in two forms: viscosity of the design (When the design preserving methods -for making a change- are harder to employ than the hacks), and viscosity of the environment (when the development environment is slow and inefficient).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, if our designs are failing due to the constant rain of changing requirements, it is &lt;u&gt;our designs that are at fault&lt;/u&gt;. We must somehow find a way to make our designs resilient to such changes and protect them from rotting.&lt;/p&gt;
&lt;h4&gt;
  
  
  Background
&lt;/h4&gt;

&lt;p&gt;The SOLID principles were first introduced by the famous Computer Scientist Robert J. Martin (a.k.a Uncle Bob) in his paper [1] in 2000. But the SOLID acronym was introduced later by Michael Feathers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The SOLID acronym stands for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;ingle Responsibility Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt;pen-Closed Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt;iskov Substitution Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;nterface Segregation Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;ependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  SOLID principles
&lt;/h2&gt;

&lt;p&gt;So, as &lt;a href="https://www.linkedin.com/in/milanmilanovic/"&gt;Dr. Milan Milanović&lt;/a&gt; Mentioned in a post &lt;a href="https://www.linkedin.com/posts/milanmilanovic_softwareengineering-softwaredeveloper-programming-activity-6997110648656547840-fsND/?utm_source=share&amp;amp;utm_medium=member_desktop"&gt;𝗛𝗼𝘄 𝗧𝗼 𝗕𝗲𝗰𝗼𝗺𝗲 𝗔 𝗚𝗿𝗲𝗮𝘁 𝗦𝗼𝗳𝘁𝘄𝗮𝗿𝗲 𝗘𝗻𝗴𝗶𝗻𝗲𝗲𝗿?&lt;/a&gt;, you should learn 𝗦𝗼𝗳𝘁𝘄𝗮𝗿𝗲 𝗘𝗻𝗴𝗶𝗻𝗲𝗲𝗿𝗶𝗻𝗴 concepts, such as: Software architecture, Design patterns &amp;amp; SOLID, etc.&lt;br&gt;
And HERE WE GO... 😍&lt;/p&gt;
&lt;h3&gt;
  
  
  1. What is the Single Responsibility Principle (SRP)?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;There should never be more than one reason for a class to change. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means that an entity (function/module/component) should do only one thing, changes &lt;u&gt;should not&lt;/u&gt; impact the overall system.&lt;/p&gt;
&lt;h4&gt;
  
  
  ⚛ &lt;u&gt;In React world:&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Every component should solve a specific problem!&lt;br&gt;
To ensure that our components are small and single purpose, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separating Data Processing Logic From the Code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the possible strategies is to create a custom hook for data fetching and filtering logic outside the component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate the Code of Data Fetching to Make it Reusable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;like making two separate hooks for Fetching data &amp;amp; Filtering data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decompose UI Components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's say we have a profile screen contains the following sections:&lt;br&gt;
Main info, Settings, Details, etc.&lt;br&gt;
Here, separate the code of the screen into different components for each section.&lt;/p&gt;

&lt;p&gt;So, the same component should NOT holds state, fetches data, and renders the result. These are more responsibilities than it should have, and it will be very fragile after multiple changes.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. What is the Open-Closed Principle (OCP)?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities should be open for extension, but closed for modification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it means the ability to add new functionality without touching the existing code for the entity to prevent the risk of creating potential bugs.&lt;/p&gt;
&lt;h4&gt;
  
  
  ⚛ &lt;u&gt;In React world:&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;It’s related to &lt;a href="https://epicreact.dev/soul-crushing-components/"&gt;Kent C. Dodds’s&lt;/a&gt; “apropcalypse”:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unfortunately, truly maintainable, flexible, simple, and reusable components require more thought than: &lt;strong&gt;“I need it to do this &lt;u&gt;differently&lt;/u&gt;, so I’ll accept a new &lt;u&gt;prop&lt;/u&gt; for that.”&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Seasoned React developers know this leads to nothing but pain and frustration for both the maintainer and user of the component.&lt;/p&gt;

&lt;p&gt;Assume that you have an &lt;code&gt;Input&lt;/code&gt; component, for now its props are: the label text, value &amp;amp; onChange func. These props can grow into large set of props, such as: icons, multiple custom labes, custom styles, focus &amp;amp; blur funcs, help &amp;amp; error texts, and so on.&lt;/p&gt;

&lt;p&gt;So the right way to start an extensible component is to use composition from the beginning; separate components for Input container, Input box, Label, Icons, Helping/error text, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;InputContainer ...props&amp;gt;
    &amp;lt;InputLabel ...props /&amp;gt;
    &amp;lt;InputPreAddon ...props /&amp;gt;
    &amp;lt;Input ...props /&amp;gt;
    &amp;lt;InputPostAddon ...props /&amp;gt;
&amp;lt;/InputContainer&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, the Input component would be closed for modifications (no need for adding too much extra props) and open for extension (adding more components on need) &lt;/p&gt;




&lt;h3&gt;
  
  
  3. What is the Liskov Substitution Principle (LSP)?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A parent should be substitutable for its child without any problem, in order to strengthen consistency so that parent and children can be used in the same way without any errors.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚛ &lt;u&gt;In React world:&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;The main takeaway from this principle is to use TypeScript. You can easily swap components if they share the same contract; like when two components use the same exact Props Interface.&lt;br&gt;
Whenever a component uses another component, it shouldn’t break its functionality (or create any surprises), here's how:&lt;br&gt;
when a component has "string" prop, but you pass it as an object! obviously the code is perfectly fine without compilation error, BUT the application is crashing!&lt;/p&gt;

&lt;p&gt;Now we'll see the importance of using TypeScript; If you want to pass anything that’s not a valid component to render (like rendering object on &lt;code&gt;Text&lt;/code&gt; component), we will get a &lt;code&gt;Type&lt;/code&gt; error. 😉&lt;/p&gt;

&lt;p&gt;And now, component that want to use another component need to follow its contract so that they don’t create any unexpected behavior.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. What is the Interface Segregation Principle (ISP)?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Classes should not be forced to implement a function they do no need in order to reduce unexpected bugs when the Class can't execute an action&lt;/p&gt;
&lt;h4&gt;
  
  
  ⚛ &lt;u&gt;In React world:&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;To remove unnecessary code from a component, We split actions into smaller sets so it only perform the actions it requires.&lt;/p&gt;

&lt;p&gt;In other words, We need to pass only the relevant information to the children components.&lt;/p&gt;

&lt;p&gt;if you have a user object contains personal info &amp;amp; social accounts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user = {
  name : "user name",
  age : "60",
  address : "user address",
  facebook : "Facebook user", 
  linkedIn : "linkedIn user"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it uses two components: &lt;code&gt;PersonalDetails&lt;/code&gt; &amp;amp; &lt;code&gt;SocialAccounts&lt;/code&gt; to show the details&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return &amp;lt;&amp;gt;
        &amp;lt;PersonalDetails user={user} /&amp;gt;
        &amp;lt;SocialAccounts user={user} /&amp;gt;
 &amp;lt;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the &lt;code&gt;PersonalDetails&lt;/code&gt; component doesn't need socials and the &lt;code&gt;SocialAccounts&lt;/code&gt; component doesn't need personal details to function so it’s clearly violating the Interface Segregation Principle.&lt;/p&gt;

&lt;p&gt;To solve the issue, you can break down user object with new keys and pass the appropriate parts to the respective components only&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user ={

  personalDetails : {
     name : "user name",
     age : "60",
     address : "user address"
  },
  socialAcounts : {
     facebook : "Facebook user", 
     linkedIn : "linkedIn user"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. What is the Dependency Inversion Principle(DIP)?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Depend upon abstractions, [not] concretions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The principle states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).&lt;/li&gt;
&lt;li&gt;Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want our classes to be open to extension (OCP), so we have reorganized our dependencies to depend on interfaces instead of concrete classes. &lt;/p&gt;

&lt;h4&gt;
  
  
  ⚛ &lt;u&gt;In React world:&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;One Component shouldn’t directly depend on another Component, but rather they both should depend on some common abstraction.&lt;br&gt;
OR&lt;br&gt;
No component or function should care about how a particular thing is done&lt;/p&gt;

&lt;p&gt;Let's say you would want your app to make use of a payment gateway like Stripe.&lt;br&gt;
You should depend on an Interface Payment component (which does NOT care about how online payment done) instead of concrete Stripe Payment component, so you can switch easily to another gateway in the future.&lt;/p&gt;




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

&lt;p&gt;In Software development, the SOLID principle works as a guideline for developers. &lt;/p&gt;

&lt;p&gt;In this article, we’ve seen how by having some flexibility with interpretations of SOLID principles, we managed to apply them to our React Flow &amp;amp; Logics and make it more clean, maintainable and robust.&lt;/p&gt;

&lt;p&gt;You should keep these principles in mind. But it’s important to remember, that you as a software developer should draw your own conclusions based on your own research. &lt;br&gt;
Thus, make sure you understand their definitions and what they do, then if you think they could be beneficial to your projects, try the methodology!&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Frameworks are temporary but concepts are permanent
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Hope SOLID principles are clear to you now. 😍&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Robert C. Martin, Design Principles and Design Patterns. Available from: &lt;a href="https://web.archive.org/web/20150906155800/http:/www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Yiğit Kemal Erinç, The SOLID Principles of Object-Oriented Programming Explained in Plain English [Internet]. freecodecamp. Available from: &lt;a href="https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Joel Olawanle, SOLID Principles for Programming and Software Design [Internet]. freecodecamp. Available from: &lt;a href="https://www.freecodecamp.org/news/solid-principles-for-programming-and-software-design/amp/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Josué Rodríguez, SOLID Principles Series. dev. Available from: &lt;a href="https://dev.to/josuerodriguez98/introduction-to-solid-principles-4o2d"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anuupadhyay, How To Use Single Responsibility Principle in ReactJS?. geeksforgeeks. Available from: &lt;a href="https://www.geeksforgeeks.org/how-to-use-single-responsibility-principle-in-reactjs/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Eduardo Moniz, Applying SOLID to react. medium. Available from: &lt;a href="https://medium.com/docler-engineering/applying-solid-to-react-ca6d1ff926a4"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mohammad Faisal, How to Apply Interface Segregation Principle in ReactJS. medium. Available from: &lt;a href="https://betterprogramming.pub/how-to-apply-interface-segregation-principle-in-reactjs-fadf77113c5d"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>solid</category>
      <category>softwaredevelopment</category>
      <category>reactnative</category>
      <category>solidprinciples</category>
    </item>
    <item>
      <title>Solution of "Could not resolve all artifacts for configuration ':react-native-iap:classpath'"</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Thu, 10 Nov 2022 09:39:20 +0000</pubDate>
      <link>https://dev.to/nour_abdou/solution-of-could-not-resolve-all-artifacts-for-configuration-react-native-iapclasspath-hhg</link>
      <guid>https://dev.to/nour_abdou/solution-of-could-not-resolve-all-artifacts-for-configuration-react-native-iapclasspath-hhg</guid>
      <description>&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Issue Scenario:
&lt;/h4&gt;

&lt;p&gt;After updating react-native-iap to resolve this issue on google play:&lt;br&gt;
&lt;code&gt;We've detected that this app uses an unsupported version of Play Billing. Please upgrade to Billing Library version 4 or newer to publish this app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The following error will raised for old RN version:&lt;br&gt;
&lt;code&gt;Could not resolve all artifacts for configuration ':react-native-iap:classpath'.&lt;/code&gt;&lt;br&gt;
   &lt;code&gt;Could not resolve org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0.&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1- Add the following to &lt;code&gt;android/build.gradle&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;buildscript {
    ext {
        ...
        kotlinVersion = '1.5.0' //&amp;lt;-- add this
    }
    ...
    dependencies {
       ...
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" //&amp;lt;-- add this

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

&lt;/div&gt;

&lt;h4&gt;
  
  
  2- To prevent &lt;code&gt;app:debugRuntimeClasspath&lt;/code&gt; error
&lt;/h4&gt;

&lt;p&gt;add this line to &lt;code&gt;android/app/build.gradle&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android {
    ...
    defaultConfig {
        ...
        missingDimensionStrategy ('store', 'play') //&amp;lt;-- add this
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  If the following error raised:
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;Execution failed for task ':react-native-iap:compilePlayDebugKotlin'. &amp;gt;Compilation error.&lt;/code&gt;&lt;br&gt;
change kotlinVersion in step-1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding 😍&lt;br&gt;
Happy Building 😌&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>reactnativeandroid</category>
    </item>
    <item>
      <title>Solution of Android resource linking failed in React Native</title>
      <dc:creator>Nour Abdou</dc:creator>
      <pubDate>Tue, 08 Nov 2022 16:33:30 +0000</pubDate>
      <link>https://dev.to/nour_abdou/solution-of-android-resource-linking-failed-in-react-native-109l</link>
      <guid>https://dev.to/nour_abdou/solution-of-android-resource-linking-failed-in-react-native-109l</guid>
      <description>&lt;h2&gt;
  
  
  ERROR
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Android resource linking failed&lt;/code&gt; error raises by some forms like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AAPT: error: resource android:attr/lStar not found&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;error: method does not override or implement a method from a supertype @Override&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AAPT: error: resource android:attr/lStar not found.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  EXPLANATION
&lt;/h2&gt;

&lt;p&gt;It often raises due to transitive dependencies for old RN projects.&lt;/p&gt;

&lt;p&gt;However, upgrading react-native version is broken. because each installed package with npm or it's dependencies could be using newer version of react-native or even the latest one.&lt;br&gt;
(check this &lt;code&gt;'com.facebook.react:react-native:+'&lt;/code&gt; in android/app/build.gradle)&lt;br&gt;
So, endless problems can bomb when you try to change packages to your current RN version.&lt;/p&gt;

&lt;p&gt;Any way, upgrading existing projects is expensive Dude! 😌&lt;/p&gt;
&lt;h2&gt;
  
  
  SOLUTION
&lt;/h2&gt;

&lt;p&gt;Don't change versions... &lt;br&gt;
Add the following block to the end of android/build.gradle file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;subprojects {
    configurations.all {
        resolutionStrategy {
            force 'com.facebook.react:react-native:${YOUR_RN_VERSION}'
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! 😃&lt;/p&gt;

&lt;p&gt;Happy Coding 😍&lt;br&gt;
Happy Buildin 😌&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>reactnativeandroid</category>
    </item>
  </channel>
</rss>
