<?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: Subrata Kumar Das</title>
    <description>The latest articles on DEV Community by Subrata Kumar Das (@subraatakumar).</description>
    <link>https://dev.to/subraatakumar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1705863%2Fa3772c0b-286a-49ea-8edc-b23b70144507.png</url>
      <title>DEV Community: Subrata Kumar Das</title>
      <link>https://dev.to/subraatakumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/subraatakumar"/>
    <language>en</language>
    <item>
      <title>Add Web Search Tool to AI Agent | Tool Calling Explained | Microsoft Foundry AI Agent Tutorial #6</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:20:56 +0000</pubDate>
      <link>https://dev.to/subraatakumar/add-web-search-tool-to-ai-agent-tool-calling-explained-microsoft-foundry-ai-agent-tutorial-6-2f3j</link>
      <guid>https://dev.to/subraatakumar/add-web-search-tool-to-ai-agent-tool-calling-explained-microsoft-foundry-ai-agent-tutorial-6-2f3j</guid>
      <description></description>
      <category>ai</category>
      <category>subraatakumar</category>
    </item>
    <item>
      <title>Deploy Your First AI Model in Microsoft Foundry | System Prompts Explained | AI Agent Course #5</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:18:12 +0000</pubDate>
      <link>https://dev.to/subraatakumar/deploy-your-first-ai-model-in-microsoft-foundry-system-prompts-explained-ai-agent-course-5-475p</link>
      <guid>https://dev.to/subraatakumar/deploy-your-first-ai-model-in-microsoft-foundry-system-prompts-explained-ai-agent-course-5-475p</guid>
      <description></description>
      <category>ai</category>
      <category>azure</category>
      <category>subraatakumar</category>
    </item>
    <item>
      <title>Microsoft Foundry Setup Tutorial | Create Your First AI Agent Project (Azure AI Foundry Course) #4</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:16:35 +0000</pubDate>
      <link>https://dev.to/subraatakumar/microsoft-foundry-setup-tutorial-create-your-first-ai-agent-project-azure-ai-foundry-course-4-28ge</link>
      <guid>https://dev.to/subraatakumar/microsoft-foundry-setup-tutorial-create-your-first-ai-agent-project-azure-ai-foundry-course-4-28ge</guid>
      <description></description>
    </item>
    <item>
      <title>What is an AI Agent? AI Agent vs Chatbot Explained | Microsoft Foundry Course #3</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:14:54 +0000</pubDate>
      <link>https://dev.to/subraatakumar/what-is-an-ai-agent-ai-agent-vs-chatbot-explained-microsoft-foundry-course-3-2fjd</link>
      <guid>https://dev.to/subraatakumar/what-is-an-ai-agent-ai-agent-vs-chatbot-explained-microsoft-foundry-course-3-2fjd</guid>
      <description></description>
      <category>ai</category>
      <category>azure</category>
      <category>beginners</category>
      <category>subrata</category>
    </item>
    <item>
      <title>What is Generative AI? Understanding the Foundation of Modern AI Agents #2</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Fri, 19 Jun 2026 06:20:04 +0000</pubDate>
      <link>https://dev.to/subraatakumar/what-is-generative-ai-understanding-the-foundation-of-modern-ai-agents-2-3jgn</link>
      <guid>https://dev.to/subraatakumar/what-is-generative-ai-understanding-the-foundation-of-modern-ai-agents-2-3jgn</guid>
      <description>&lt;p&gt;Everyone is talking about AI Agents.&lt;/p&gt;

&lt;p&gt;But before you build an AI Agent, there is one concept you absolutely need to understand:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generative AI.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generative AI is the technology that transformed software from systems that simply follow rules into systems that can understand language, generate responses, reason through instructions, and assist users in a natural way.&lt;/p&gt;

&lt;p&gt;As part of my new course:&lt;/p&gt;

&lt;h2&gt;
  
  
  Develop Your First AI Agent with Microsoft Foundry
&lt;/h2&gt;

&lt;p&gt;I published the first lesson where we explore the journey from traditional software to Generative AI and understand why modern AI Agents became possible.&lt;/p&gt;

&lt;p&gt;🎥 &lt;strong&gt;Watch the video here:&lt;/strong&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/aGmA574q_FQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Topic Matters
&lt;/h2&gt;

&lt;p&gt;Many developers jump directly into AI Agents, prompts, tools, and frameworks.&lt;/p&gt;

&lt;p&gt;However, without understanding the evolution of AI, it becomes difficult to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why AI Agents exist&lt;/li&gt;
&lt;li&gt;Why Large Language Models are important&lt;/li&gt;
&lt;li&gt;Why prompts work&lt;/li&gt;
&lt;li&gt;Why tools are needed&lt;/li&gt;
&lt;li&gt;How modern AI systems actually operate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this lesson, we start from first principles and build the foundation required for the rest of the course.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You'll Learn
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Traditional Software
&lt;/h3&gt;

&lt;p&gt;For decades, software followed a simple pattern:&lt;/p&gt;

&lt;p&gt;Input → Rules → Output&lt;/p&gt;

&lt;p&gt;Developers explicitly defined every behavior.&lt;/p&gt;

&lt;p&gt;This worked well until humans started interacting with software using natural language.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Rule-Based Systems Break
&lt;/h3&gt;

&lt;p&gt;Imagine building a dietician chatbot.&lt;/p&gt;

&lt;p&gt;Users might ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What should I eat?&lt;/li&gt;
&lt;li&gt;Suggest a healthy breakfast.&lt;/li&gt;
&lt;li&gt;What foods contain protein?&lt;/li&gt;
&lt;li&gt;Can I eat oats daily?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these questions are similar.&lt;/p&gt;

&lt;p&gt;Yet they are phrased differently.&lt;/p&gt;

&lt;p&gt;Supporting thousands of variations quickly becomes impossible with manually written rules.&lt;/p&gt;




&lt;h3&gt;
  
  
  Predictive AI
&lt;/h3&gt;

&lt;p&gt;Machine Learning introduced a new approach.&lt;/p&gt;

&lt;p&gt;Instead of writing rules, we train models using data.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spam Detection&lt;/li&gt;
&lt;li&gt;Fraud Detection&lt;/li&gt;
&lt;li&gt;Recommendation Systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Predictive AI can make decisions.&lt;/p&gt;

&lt;p&gt;But it still cannot create content.&lt;/p&gt;




&lt;h3&gt;
  
  
  Prediction vs Creation
&lt;/h3&gt;

&lt;p&gt;A predictive model can answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fraud probability: 87%&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But can it explain why?&lt;/p&gt;

&lt;p&gt;Can it write a detailed report?&lt;/p&gt;

&lt;p&gt;Can it create a personalized recommendation?&lt;/p&gt;

&lt;p&gt;Not naturally.&lt;/p&gt;

&lt;p&gt;This limitation led to the rise of Generative AI.&lt;/p&gt;




&lt;h3&gt;
  
  
  Generative AI
&lt;/h3&gt;

&lt;p&gt;Generative AI creates new content.&lt;/p&gt;

&lt;p&gt;It can generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Audio&lt;/li&gt;
&lt;li&gt;Video&lt;/li&gt;
&lt;li&gt;Code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of selecting predefined responses, it dynamically creates new outputs based on user prompts.&lt;/p&gt;




&lt;h3&gt;
  
  
  Large Language Models (LLMs)
&lt;/h3&gt;

&lt;p&gt;At the heart of Generative AI are Large Language Models.&lt;/p&gt;

&lt;p&gt;LLMs learn language patterns from enormous amounts of data and use those patterns to generate human-like responses.&lt;/p&gt;

&lt;p&gt;This is the technology behind modern AI systems such as ChatGPT, Microsoft Copilot, Gemini, Claude, and many others.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Generative AI Flow
&lt;/h3&gt;

&lt;p&gt;Every Generative AI application follows a simple architecture:&lt;/p&gt;

&lt;p&gt;User Prompt → LLM → Generated Response&lt;/p&gt;

&lt;p&gt;Understanding this flow is critical because it becomes the foundation of AI Agent architectures.&lt;/p&gt;




&lt;h3&gt;
  
  
  AI Agent Architecture
&lt;/h3&gt;

&lt;p&gt;In the second half of the course, we will build an AI Agent using Microsoft Foundry.&lt;/p&gt;

&lt;p&gt;The architecture we'll implement is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
↓&lt;br&gt;
React + Vite Frontend&lt;br&gt;
↓&lt;br&gt;
Microsoft Foundry Agent&lt;br&gt;
├── Instructions&lt;br&gt;
├── Generative AI Model&lt;br&gt;
└── Web Search Tool&lt;br&gt;
↓&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;Understanding Generative AI is the first step toward understanding this architecture.&lt;/p&gt;




&lt;h3&gt;
  
  
  Introducing Subra AI Dietician
&lt;/h3&gt;

&lt;p&gt;Throughout the course, we will build:&lt;/p&gt;

&lt;h2&gt;
  
  
  Subra AI Dietician
&lt;/h2&gt;

&lt;p&gt;A practical AI-powered dietician assistant that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answer nutrition questions&lt;/li&gt;
&lt;li&gt;Provide healthy food suggestions&lt;/li&gt;
&lt;li&gt;Follow custom instructions&lt;/li&gt;
&lt;li&gt;Use web search when required&lt;/li&gt;
&lt;li&gt;Respond through a modern web interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of the course, you'll have a complete working AI Agent built using Microsoft Foundry.&lt;/p&gt;




&lt;h2&gt;
  
  
  Video Chapters
&lt;/h2&gt;

&lt;p&gt;00:00 Introduction&lt;/p&gt;

&lt;p&gt;01:30 The Problem With Traditional Software&lt;/p&gt;

&lt;p&gt;02:30 Why Rule-Based Systems Break&lt;/p&gt;

&lt;p&gt;03:51 The Rise of Predictive AI&lt;/p&gt;

&lt;p&gt;05:06 Prediction vs Creation&lt;/p&gt;

&lt;p&gt;05:55 What is Generative AI&lt;/p&gt;

&lt;p&gt;06:43 What is LLM?&lt;/p&gt;

&lt;p&gt;07:36 The Generative AI Flow&lt;/p&gt;

&lt;p&gt;08:18 AI Agent Architecture&lt;/p&gt;

&lt;p&gt;09:06 Subra AI Dietician&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Coming Next?
&lt;/h2&gt;

&lt;p&gt;In the next lesson, we'll answer a very important question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If Generative AI can already answer questions, why do we need AI Agents?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI Assistant vs AI Agent&lt;/li&gt;
&lt;li&gt;Instructions&lt;/li&gt;
&lt;li&gt;Tools&lt;/li&gt;
&lt;li&gt;Reasoning&lt;/li&gt;
&lt;li&gt;Agent Workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and prepare for building our first Microsoft Foundry Agent.&lt;/p&gt;

&lt;p&gt;If you're interested in AI Engineering, Microsoft Foundry, Azure AI, Agentic AI, or building practical AI applications, this series is designed for you.&lt;/p&gt;

&lt;p&gt;Happy learning!&lt;/p&gt;

&lt;p&gt;— Subrata Kumar Das&lt;br&gt;
🌐 subraatakumar.com&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>microsoft</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Develop Your First AI Agent with Microsoft Foundry</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Thu, 18 Jun 2026 06:11:35 +0000</pubDate>
      <link>https://dev.to/subraatakumar/develop-your-first-ai-agent-with-microsoft-foundry-2ben</link>
      <guid>https://dev.to/subraatakumar/develop-your-first-ai-agent-with-microsoft-foundry-2ben</guid>
      <description>&lt;h1&gt;
  
  
  Develop Your First AI Agent with Microsoft Foundry – Course Launch
&lt;/h1&gt;

&lt;p&gt;AI Agents are quickly moving from experimental technology to real-world software engineering solutions.&lt;/p&gt;

&lt;p&gt;As developers, we are entering a phase where applications can not only respond to user input but also reason, use tools, search for information, and perform tasks on behalf of users.&lt;/p&gt;

&lt;p&gt;To help software engineers get started with this technology, I've launched a new hands-on course:&lt;/p&gt;

&lt;h2&gt;
  
  
  Develop Your First AI Agent with Microsoft Foundry
&lt;/h2&gt;

&lt;p&gt;This course focuses on practical implementation rather than AI theory.&lt;/p&gt;

&lt;p&gt;Throughout the series, we'll build a complete application called &lt;strong&gt;Subra AI Dietician&lt;/strong&gt;, an intelligent AI Agent powered by Microsoft Foundry and Azure AI Foundry Agent Service.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Build
&lt;/h2&gt;

&lt;p&gt;By the end of the course, you'll have built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Microsoft Foundry AI Agent&lt;/li&gt;
&lt;li&gt;Custom Agent Instructions&lt;/li&gt;
&lt;li&gt;Web Search Tool Integration&lt;/li&gt;
&lt;li&gt;Agent Testing and Evaluation&lt;/li&gt;
&lt;li&gt;A Deployed AI Agent&lt;/li&gt;
&lt;li&gt;A React Frontend Connected to the Agent&lt;/li&gt;
&lt;li&gt;A Complete End-to-End AI Application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Foundry&lt;/li&gt;
&lt;li&gt;Azure AI Foundry Agent Service&lt;/li&gt;
&lt;li&gt;Visual Studio Code&lt;/li&gt;
&lt;li&gt;GitHub Copilot&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who Is This Course For?
&lt;/h2&gt;

&lt;p&gt;This course is designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Software Engineers&lt;/li&gt;
&lt;li&gt;React Developers&lt;/li&gt;
&lt;li&gt;React Native Developers&lt;/li&gt;
&lt;li&gt;Full Stack Developers&lt;/li&gt;
&lt;li&gt;Technical Leads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No prior AI experience is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1 Is Now Available
&lt;/h2&gt;

&lt;p&gt;The first lesson introduces the course, explains what we'll build, and walks through the complete project roadmap.&lt;/p&gt;

&lt;p&gt;📺 Watch the video:&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/qILE6NUEsQU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;🌐 Course Website:&lt;br&gt;
&lt;a href="https://rnm.subraatakumar.com" rel="noopener noreferrer"&gt;https://rnm.subraatakumar.com&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In the next lesson, we'll answer an important question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What exactly is an AI Agent, and how is it different from traditional software applications?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear from the community:&lt;/p&gt;

&lt;p&gt;What AI Agent would you build for your organization or personal projects?&lt;/p&gt;

&lt;h1&gt;
  
  
  ai #microsoft #azure #aifoundry #microsoftfoundry #aiagents #softwareengineering #react #reactnative #webdevelopment #githubcopilot
&lt;/h1&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>microsoft</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lesson 1.3 - GraphQL for Screen Complexity and App Changes</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 17 Jun 2026 05:07:25 +0000</pubDate>
      <link>https://dev.to/subraatakumar/lesson-13-graphql-for-screen-complexity-and-app-changes-3cdi</link>
      <guid>https://dev.to/subraatakumar/lesson-13-graphql-for-screen-complexity-and-app-changes-3cdi</guid>
      <description>&lt;p&gt;Good morning, class! Welcome back. In our last lesson, we explored how GraphQL fundamentally addresses the issues of over-fetching and under-fetching.&lt;/p&gt;

&lt;p&gt;Today, we are going to connect those architectural concepts directly to real-world React Native screen complexity. Our &lt;strong&gt;Goal&lt;/strong&gt; today is to understand how GraphQL simplifies your codebase when a screen demands multiple data sources, when different screens require entirely unique variations of the same resource, and when your mobile application changes and evolves over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Problem One: Codebase Complexity via Multiple API Calls
&lt;/h2&gt;

&lt;p&gt;Making multiple API calls is not inherently wrong, but from a mobile product engineering perspective, it introduces a significant amount of state-tracking boilerplate inside your components.&lt;/p&gt;

&lt;p&gt;In a traditional React Native screen driven by REST, managing multiple endpoints often forces you into a state management pattern that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProducts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCategories&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loadingProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoadingProducts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;loadingCategories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoadingCategories&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;productsError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProductsError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;categoriesError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCategoriesError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Class, look closely at this block of code. We haven't even written a single line of JSX or rendered any UI yet, and our component is already drowning in individual state hooks just to track the network layer.&lt;/p&gt;

&lt;p&gt;The moment a single screen relies on multiple independent asynchronous requests, you are forced to programmatically answer complex state orchestration questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the &lt;em&gt;entire&lt;/em&gt; screen considered to be in a loading state, or are individual sub-sections loading independently?&lt;/li&gt;
&lt;li&gt;What happens visually if the product list resolves successfully, but the category chip request fails?&lt;/li&gt;
&lt;li&gt;When a user triggers a pull-to-refresh action, should it aggressively retry every single request?&lt;/li&gt;
&lt;li&gt;Should a localized network failure on a non-critical widget block the user from interacting with the rest of the screen?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. GraphQL Fix One: Consolidated Screen-Level Operations
&lt;/h2&gt;

&lt;p&gt;Instead of forcing your UI components to orchestrate several disconnected REST endpoints, a single GraphQL operation lets you fetch the precise combination of data pieces your screen needs in one single network round-trip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HomeScreenData&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="n"&gt;categories&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;meta&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="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;pages&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;category&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;Now, let's be entirely clear: this does not magically erase the necessity for loading spinners or error screens. You still need to design and implement resilient UI fallbacks.&lt;/p&gt;

&lt;p&gt;However, it vastly simplifies your frontend state logic. It collapses multiple asynchronous workflows down into &lt;strong&gt;one single operation&lt;/strong&gt; for your component to reason about, dramatically reducing the state variables you need to manually track.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Problem Two: Screen-Specific Data Requirements
&lt;/h2&gt;

&lt;p&gt;As an application grows, different mobile screens will inevitably demand entirely different variations of the exact same data model. Let’s map out a standard e-commerce flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product List Screen Layout:&lt;/strong&gt; Only needs &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, and &lt;code&gt;imageUrl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Details Screen Layout:&lt;/strong&gt; Requires &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;imageUrl&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;brand&lt;/code&gt;, &lt;code&gt;rating&lt;/code&gt;, &lt;code&gt;discount&lt;/code&gt;, and &lt;code&gt;inStock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cart Summary Screen Layout:&lt;/strong&gt; Demands &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;quantity&lt;/code&gt;, and &lt;code&gt;inStock&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a traditional REST architecture, backend teams typically handle these evolving variations by creating specific hyper-targeted endpoints (like &lt;code&gt;/api/v1/products/cart-view&lt;/code&gt;) or by adding heavy configurations of query parameters (like &lt;code&gt;/products?include=details&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;While this can get the job done, over time it causes your API surface area to balloon into a tangled, unmanageable mess simply because every new screen design requires a slightly modified data payload shape.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. GraphQL Fix Two: Component-Driven Selection Sets
&lt;/h2&gt;

&lt;p&gt;GraphQL shifts data model ownership back to the client application. Instead of waiting on backend adjustments, &lt;strong&gt;each specific screen explicitly declares its own data requirements.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, you can parameterize these operations dynamically using &lt;strong&gt;GraphQL Variables&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProductListScreen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&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="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$category&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="n"&gt;meta&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="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;pages&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;inStock&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;To execute this operation with dynamic filtering, you pass a separate &lt;strong&gt;Variables object&lt;/strong&gt; alongside the query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fruits"&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;The underlying structural template of the query remains completely stable. The runtime variables change fluidly based on user interaction. This exact paradigm is exactly what makes building mobile filters, search views, and infinite-scrolling lists highly predictable and clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Problem Three: The Production Reality of App Versioning
&lt;/h2&gt;

&lt;p&gt;Unlike web applications where a new deployment updates all users instantly, mobile applications stay installed on user devices for months or even years.&lt;/p&gt;

&lt;p&gt;If a backend team alters or refactors a REST response payload, older, un-updated installations of your mobile app out in the wild can instantly crash. Because of this, mobile engineering teams are traditionally forced to implement strict, complex API versioning policies (like &lt;code&gt;/api/v1/&lt;/code&gt; vs &lt;code&gt;/api/v2/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;GraphQL does not replace architectural discipline, but it offers natural protection against breaking changes because &lt;strong&gt;the client must explicitly request the fields it intends to use.&lt;/strong&gt; If an older mobile app build doesn't know about a new &lt;code&gt;rating&lt;/code&gt; field, it simply won't request it. If a newer build needs to display it, you append it inline without affecting old versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProductCards&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="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Added seamlessly for new app versions&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;Because the backend server knows exactly which fields are being requested by current active users, the client app is no longer tightly coupled to a monolithic, fixed response shape.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. The Blueprint: Predictable Response Mirroring
&lt;/h2&gt;

&lt;p&gt;One of the most beginner-friendly and elegant aspects of working with GraphQL is that &lt;strong&gt;the response payload shape directly mirrors your request query structure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s trace an active transaction:&lt;/p&gt;

&lt;h3&gt;
  
  
  Client Query Document:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CategoriesAndProducts&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="n"&gt;categories&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  JSON Server Response:
&lt;/h3&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;"data"&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;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Fruits"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vegetables"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"products"&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;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apple"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tomato"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;While the literal data values inside the strings and arrays will change based on database records, the structural nesting matches your query word-for-word, making data binding inside React Native components entirely intuitive.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Guided Practice in GraphiQL
&lt;/h2&gt;

&lt;p&gt;Before we jump back into our mobile IDEs, let's build muscular memory by sandbox testing this query layout inside GraphiQL:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate your web browser to &lt;code&gt;https://backend.ecom.subraatakumar.com/graphiql&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Paste the parameterized &lt;code&gt;ProductListScreen&lt;/code&gt; query into the main editor panel.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Query Variables&lt;/strong&gt; drawer at the bottom left and pass valid page/category variables.&lt;/li&gt;
&lt;li&gt;Hit the &lt;strong&gt;Play&lt;/strong&gt; button to execute.&lt;/li&gt;
&lt;li&gt;Experiment: adjust the &lt;code&gt;category&lt;/code&gt; string to another value and re-run.&lt;/li&gt;
&lt;li&gt;Delete &lt;code&gt;imageUrl&lt;/code&gt; from the selection set and observe the updated JSON structure.&lt;/li&gt;
&lt;li&gt;Append &lt;code&gt;rating&lt;/code&gt; to the selection set, execute, and verify the structural response mirrors your query change instantly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This iterative feedback loop is the core day-to-day workflow of a productive GraphQL developer.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. React Native Low-Level Implementation
&lt;/h2&gt;

&lt;p&gt;Let’s observe how this complete multi-resource request compiles into a low-level JavaScript module using our temporary native &lt;code&gt;fetch&lt;/code&gt; client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadProductList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://backend.ecom.subraatakumar.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        query ProductListScreen($page: Int!, $size: Int!, $category: String) {
          products(page: $page, size: $size, category: $category) {
            meta {
              total
              page
              pages
            }
            data {
              id
              name
              price
              imageUrl
              inStock
            }
          }
        }
      `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Check Your Understanding
&lt;/h2&gt;

&lt;p&gt;Before we wrap up this theory session and head into our practical labs, make sure you can answer these three questions clearly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How do multiple independent REST calls compound the structural complexity of component loading and error states in React Native?&lt;/li&gt;
&lt;li&gt;What does it mean for a screen to "own its data requirement," and how does this prevent API endpoint bloat on the backend?&lt;/li&gt;
&lt;li&gt;What is the relationship between the structural layout of a GraphQL query document and the eventual JSON payload returned by the server?&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Great work today, class. Review your notes, spend 10 minutes testing variations in the GraphiQL playground, and I will see you all in our next session!&lt;/p&gt;




&lt;p&gt;Connect with me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/TechCraft-By-Subrata" rel="noopener noreferrer"&gt;https://github.com/TechCraft-By-Subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/subraatakumar/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YouTube: &lt;a href="https://www.youtube.com/@techcraftclub" rel="noopener noreferrer"&gt;https://www.youtube.com/@techcraftclub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Instagram: &lt;a href="https://www.instagram.com/subraatakumar/" rel="noopener noreferrer"&gt;https://www.instagram.com/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reddit: &lt;a href="https://www.reddit.com/r/ReactNativeMastery/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/ReactNativeMastery/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DEV.to: &lt;a href="https://dev.to/subraatakumar"&gt;https://dev.to/subraatakumar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.gg/cA5fhVT8" rel="noopener noreferrer"&gt;https://discord.gg/cA5fhVT8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WhatsApp: &lt;a href="https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M" rel="noopener noreferrer"&gt;https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Topmate: &lt;a href="https://topmate.io/subrata" rel="noopener noreferrer"&gt;https://topmate.io/subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Native Mastery: &lt;a href="https://rnm.subraatakumar.com/" rel="noopener noreferrer"&gt;https://rnm.subraatakumar.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>mobile</category>
      <category>reactnative</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lesson 1.2 - REST Problems and the First GraphQL Fixes</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 17 Jun 2026 04:28:49 +0000</pubDate>
      <link>https://dev.to/subraatakumar/lesson-12-rest-problems-and-the-first-graphql-fixes-2alm</link>
      <guid>https://dev.to/subraatakumar/lesson-12-rest-problems-and-the-first-graphql-fixes-2alm</guid>
      <description>&lt;p&gt;Good morning, everyone! Welcome back. In our previous lesson, we compared REST and GraphQL at a high, architectural level.&lt;/p&gt;

&lt;p&gt;Today, we are going one layer deeper. Our &lt;strong&gt;Goal&lt;/strong&gt; today is to analyze the first two critical API data-fetching problems that show up repeatedly in production-grade React Native applications: &lt;strong&gt;over-fetching&lt;/strong&gt; and &lt;strong&gt;under-fetching&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding these two issues will show you exactly why so many engineering teams choose to migrate their mobile applications to GraphQL.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Problem One: Over-Fetching
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Over-fetching&lt;/strong&gt; simply means that the backend API sends significantly more data fields over the wire than your specific screen layout actually requires to render.&lt;/p&gt;

&lt;p&gt;Let's look at a concrete mobile use case. Imagine you are building a product preview card for a grid view. The UI layout only displays three pieces of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product image&lt;/li&gt;
&lt;li&gt;Product name&lt;/li&gt;
&lt;li&gt;Price&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, when you fire a request to your standard REST endpoint, the server hands you back this entire payload block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fruits"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"imageUrl"&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://example.com/apple.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fresh red apples"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Farm Fresh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inStock"&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;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"unit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.7&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;Look at that JSON object. While properties like &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;quantity&lt;/code&gt;, &lt;code&gt;unit&lt;/code&gt;, and &lt;code&gt;brand&lt;/code&gt; are absolutely vital when a user clicks through to a dedicated &lt;em&gt;Product Details&lt;/em&gt; screen, they are completely useless waste on a high-level catalog screen.&lt;/p&gt;

&lt;p&gt;When developing for mobile devices, this extra payload volume is not harmless metadata. Your users are interacting with your app on the move—often navigating fluctuating cellular networks, capped data plans, hardware with limited memory overhead, and battery-sensitive operating conditions. Wasting bytes on fields that are immediately discarded strains those mobile resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. GraphQL Fix One: Ask for Only the Needed Fields
&lt;/h2&gt;

&lt;p&gt;GraphQL eliminates this waste by putting selection power back in the hands of the client interface.&lt;/p&gt;

&lt;p&gt;When rendering our simple product preview cards, we can construct a selection set containing exclusively the fields our layout binds to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProductCards&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="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&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;Now, let’s look at how the exact same schema resource behaves when we shift context over to the comprehensive &lt;em&gt;Product Details&lt;/em&gt; screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProductDetails&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="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;brand&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;inStock&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;Notice the power here: &lt;strong&gt;We are hitting the exact same data resource gateway, but with completely different selection sets tailored perfectly to distinct UI requirements.&lt;/strong&gt; That is our first major GraphQL architectural fix.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Problem Two: Under-Fetching
&lt;/h2&gt;

&lt;p&gt;Conversely, &lt;strong&gt;Under-fetching&lt;/strong&gt; means that a single endpoint fails to provide enough comprehensive data to satisfy what a single screen layout needs to render.&lt;/p&gt;

&lt;p&gt;Consider a modern, highly dynamic e-commerce marketplace Home Screen. To provide a rich landing experience, this view simultaneously requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A featured list of trending products&lt;/li&gt;
&lt;li&gt;A horizontal scrolling list of category chips&lt;/li&gt;
&lt;li&gt;The logged-in user's active shopping cart context or recent order history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a traditional REST architecture, this structural layout regularly forces you to coordinate and chain together multiple independent network requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/v1/products?page=1&amp;amp;size=10
GET /api/v1/categories
GET /api/v1/orders

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

&lt;/div&gt;



&lt;p&gt;As a mobile developer, this shifts a heavy orchestration burden onto your React Native codebase. Your UI layer suddenly has to elegantly coordinate three separate asynchronous network cycles, manage multiple individual loading spinners, catch unique localized error states, and configure fallback retry paths if request two fails while requests one and three succeed.&lt;/p&gt;

&lt;p&gt;This state complexity isn't a theoretical edge case—it is a production reality that compounds quickly as mobile layout requirements grow.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. GraphQL Fix Two: Request Related Data Together
&lt;/h2&gt;

&lt;p&gt;GraphQL cleanly resolves under-fetching by allowing client components to request multiple, completely distinct root resource fields inside a single, unified network transaction block.&lt;/p&gt;

&lt;p&gt;Here is how we can aggregate our homepage data requirements into a clean operational query payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HomeScreenData&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="n"&gt;categories&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;meta&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="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;pages&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;category&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;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;A quick note on architecture:&lt;/strong&gt; This does not mean you should bundle every single piece of data across your entire application into one gargantuan query document. It simply means that GraphQL hands you a flexible API layer capable of cleanly packaging related data blocks into a single round-trip whenever it makes your UI rendering architecture simpler and cleaner.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. React Native Implementation Example
&lt;/h2&gt;

&lt;p&gt;Let’s look at how this unified homepage fetching logic translates into a low-level JavaScript function within a mobile environment using standard &lt;code&gt;fetch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadHomeScreenData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://backend.ecom.subraatakumar.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        query HomeScreenData {
          categories
          products(page: 1, size: 10) {
            data {
              id
              name
              price
              imageUrl
              category
            }
          }
        }
      `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Just like in our previous exercises, we are intentionally executing this request through raw HTTP &lt;code&gt;fetch&lt;/code&gt; syntax so you can clearly trace the structural shape of the network request body. We will abstract this boilerplate code away with Apollo Client once we enter Module 3.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Core Takeaways
&lt;/h2&gt;

&lt;p&gt;The fundamental advantage of introducing GraphQL into your mobile stack isn't based on magic. It boils down to two straightforward client-side performance principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mobile client can request less&lt;/strong&gt; when rendering lightweight, targeted UI elements (Fixing Over-fetching).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The mobile client can request more data fields aggregated together&lt;/strong&gt; when populating complex, multi-source layouts (Fixing Under-fetching).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This dual-axis optimization immediately simplifies state management routines and lowers data overhead on mobile devices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Check Your Understanding
&lt;/h2&gt;

&lt;p&gt;Take a brief moment to review these questions silently to ensure today's architectural concepts are locked in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your own words, what is the core operational cost of &lt;strong&gt;over-fetching&lt;/strong&gt; in a cellular mobile application environment?&lt;/li&gt;
&lt;li&gt;How does &lt;strong&gt;under-fetching&lt;/strong&gt; directly complicate state and error management inside your React Native UI components?&lt;/li&gt;
&lt;li&gt;What mechanism does GraphQL use to grant the mobile client complete control over the structural shape of the incoming response payload?&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  External Reading
&lt;/h2&gt;

&lt;p&gt;To expand on these core design topics before we start our upcoming practical coding session, explore these official reference guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://graphql.org/learn/" rel="noopener noreferrer"&gt;GraphQL Core Concepts: Over-fetching vs Under-fetching Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/" rel="noopener noreferrer"&gt;MDN Web Docs: Optimizing Mobile Performance Over Cellular Networks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Excellent concentration today, everyone. Pack up your laptops, and I will see you all in our next session!&lt;/p&gt;




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

&lt;p&gt;Connect with me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/TechCraft-By-Subrata" rel="noopener noreferrer"&gt;https://github.com/TechCraft-By-Subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/subraatakumar/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YouTube: &lt;a href="https://www.youtube.com/@techcraftclub" rel="noopener noreferrer"&gt;https://www.youtube.com/@techcraftclub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Instagram: &lt;a href="https://www.instagram.com/subraatakumar/" rel="noopener noreferrer"&gt;https://www.instagram.com/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reddit: &lt;a href="https://www.reddit.com/r/ReactNativeMastery/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/ReactNativeMastery/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DEV.to: &lt;a href="https://dev.to/subraatakumar"&gt;https://dev.to/subraatakumar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.gg/cA5fhVT8" rel="noopener noreferrer"&gt;https://discord.gg/cA5fhVT8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WhatsApp: &lt;a href="https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M" rel="noopener noreferrer"&gt;https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Topmate: &lt;a href="https://topmate.io/subrata" rel="noopener noreferrer"&gt;https://topmate.io/subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Native Mastery: &lt;a href="https://rnm.subraatakumar.com/" rel="noopener noreferrer"&gt;https://rnm.subraatakumar.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>reactnative</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lesson 1.1 - REST vs GraphQL</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Fri, 12 Jun 2026 05:04:55 +0000</pubDate>
      <link>https://dev.to/subraatakumar/lesson-11-rest-vs-graphql-490k</link>
      <guid>https://dev.to/subraatakumar/lesson-11-rest-vs-graphql-490k</guid>
      <description>&lt;h1&gt;
  
  
  Lesson 1.1 - REST vs GraphQL
&lt;/h1&gt;

&lt;p&gt;Good morning, class! Welcome to the very first lesson of our course.&lt;/p&gt;

&lt;p&gt;Before we jump ahead to writing Apollo Client code, before we discuss caching mechanisms, and before we start layout development on our mobile product screens, we need to anchor ourselves in a fundamental architectural concept: the core operational differences between REST and GraphQL.&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;Goal&lt;/strong&gt; today is highly focused: we are going to look at both API communication styles strictly from the perspective of a React Native developer building real-world, data-driven mobile screens.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The API Problem Every Mobile App Has
&lt;/h2&gt;

&lt;p&gt;Let’s be honest: every mobile application is essentially a visual wrapper around data.&lt;/p&gt;

&lt;p&gt;A product list screen needs product records. A category filter drawer needs taxonomy trees. A checkout screen needs historical order logs. The architectural hurdle is never about &lt;em&gt;whether&lt;/em&gt; your frontend application needs to communicate with a backend database. The real problem we face daily is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How does a specific screen efficiently request the exact data it needs to render its layout?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;REST and GraphQL approach this exact question from completely opposite engineering mindsets.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What REST Looks Like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;REST (Representational State Transfer)&lt;/strong&gt; is an API design style where the backend exposes data through multiple individual URLs, which we refer to as &lt;strong&gt;Endpoints&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at these real examples from our e-commerce backend architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://backend.ecom.subraatakumar.com/api/v1/products?page=1&amp;amp;size=10
GET https://backend.ecom.subraatakumar.com/api/v1/categories

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

&lt;/div&gt;



&lt;p&gt;In a traditional REST architecture, &lt;strong&gt;the endpoint dictates the shape of the data payload&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the backend team configured the &lt;code&gt;/products&lt;/code&gt; endpoint to return 45 data fields per item block, your React Native app will pull all 45 fields over the cellular network—even if your mobile layout only renders 3 of them (like &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, and &lt;code&gt;imageUrl&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This doesn't make REST inherently bad. REST is deeply familiar, straightforward, predictable, and runs a massive portion of the modern web. However, as mobile application layouts become highly tailored and dynamic, REST can occasionally back the client application into a corner, forcing it to swallow rigid data footprints designed for desktop environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. What GraphQL Looks Like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GraphQL&lt;/strong&gt; is a strongly-typed query language and runtime for APIs.&lt;/p&gt;

&lt;p&gt;Instead of forcing your mobile UI to hit a dozen disconnected endpoints to build a single view, a GraphQL app sends a declarative query to a &lt;strong&gt;Single, Unified Endpoint&lt;/strong&gt; and explicitly dictates the exact fields it requires to render its current layout view.&lt;/p&gt;

&lt;p&gt;Our e-commerce GraphQL gateway address is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://backend.ecom.subraatakumar.com/graphql

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

&lt;/div&gt;



&lt;p&gt;Here is a look at a basic query document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProductList&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="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;data&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="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;imageUrl&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;If you read this code block like a plain English sentence, it says:&lt;br&gt;
&lt;em&gt;"Dear backend server, for this specific mobile product list screen, fetch page 1 containing 10 items, but only return the &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, and &lt;code&gt;imageUrl&lt;/code&gt; fields for those items. Leave everything else behind."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the first critical mental paradigm shift you must master.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. The Main Architectural Difference
&lt;/h2&gt;

&lt;p&gt;To put it in simplest terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST is Endpoint-First.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GraphQL is Screen-Data-First.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's break down the developer thought process side-by-side:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Architectural Approach&lt;/th&gt;
&lt;th&gt;Core Question Asked by Frontend Dev&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;REST Mindset&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;"Which specific endpoint or collection of URLs gives me access to this resource?"&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GraphQL Mindset&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;"What are the precise data properties this specific screen component needs to render right now?"&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For React Native engineers, this distinction is crucial. Mobile apps operate on smaller displays, run on resource-constrained hardware, and face erratic cellular network performance. Eliminating bloated payloads directly improves app responsiveness.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. REST Request Example
&lt;/h2&gt;

&lt;p&gt;Let’s look at a standard JavaScript implementation fetching data from our REST endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchProductsWithRest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://backend.ecom.subraatakumar.com/api/v1/products?page=1&amp;amp;size=10&lt;/span&gt;&lt;span class="dl"&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to load products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;Notice the key mechanical takeaway here: &lt;strong&gt;The URL structure completely controls what data payload drops into your application state.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. GraphQL Request Example
&lt;/h2&gt;

&lt;p&gt;Now, let’s observe how we accomplish the exact same product fetching intent using GraphQL via low-level native &lt;code&gt;fetch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchProductsWithGraphQL&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://backend.ecom.subraatakumar.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        query ProductList {
          products(page: 1, size: 10) {
            data {
              id
              name
              price
              imageUrl
            }
          }
        }
      `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Notice the functional shift here: &lt;strong&gt;The HTTP endpoint stays completely static, but the inner query payload directly controls the shape and size of the incoming response.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. What React Native Developers Should Remember
&lt;/h2&gt;

&lt;p&gt;A common beginner pitfall is framing this engineering choice as an absolute binary battle: &lt;em&gt;"REST vs GraphQL—which tool wins?"&lt;/em&gt; That is entirely the wrong lens to view your system architecture through.&lt;/p&gt;

&lt;p&gt;The useful question you should be asking yourself as a mobile product engineer is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Can my current screen component request only the exact properties it requires to render its layout, within the fewest possible round-trips over the network?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GraphQL was engineered specifically from the ground up to solve that exact optimization problem for client apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Check Your Understanding
&lt;/h2&gt;

&lt;p&gt;Before packed up and heading out to our next hands-on coding lab, make sure you can confidently answer these three architectural review questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In a traditional REST API ecosystem, who fundamentally controls the structural shape of the data response?&lt;/li&gt;
&lt;li&gt;In a GraphQL ecosystem, who assumes control over choosing which data fields are returned for a mobile screen layout?&lt;/li&gt;
&lt;li&gt;Why does minimizing raw payload size and network round-trips matter significantly more for mobile hardware form factors than desktop web browsers?&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  External Reading
&lt;/h2&gt;

&lt;p&gt;To deepen your grasp of these concepts before our next class, review these foundational resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://graphql.org/learn/queries/" rel="noopener noreferrer"&gt;GraphQL Official Documentation: Queries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://graphql.org/learn/serving-over-http/" rel="noopener noreferrer"&gt;GraphQL Official Documentation: Serving over HTTP Specs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great job keeping focus today. I'll see you all in the next lecture!&lt;/p&gt;




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

&lt;p&gt;Connect with me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/TechCraft-By-Subrata" rel="noopener noreferrer"&gt;https://github.com/TechCraft-By-Subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/subraatakumar/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YouTube: &lt;a href="https://www.youtube.com/@techcraftclub" rel="noopener noreferrer"&gt;https://www.youtube.com/@techcraftclub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Instagram: &lt;a href="https://www.instagram.com/subraatakumar/" rel="noopener noreferrer"&gt;https://www.instagram.com/subraatakumar/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reddit: &lt;a href="https://www.reddit.com/r/ReactNativeMastery/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/ReactNativeMastery/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DEV.to: &lt;a href="https://dev.to/subraatakumar"&gt;https://dev.to/subraatakumar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.gg/cA5fhVT8" rel="noopener noreferrer"&gt;https://discord.gg/cA5fhVT8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WhatsApp: &lt;a href="https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M" rel="noopener noreferrer"&gt;https://whatsapp.com/channel/0029VbCz72vFCCoUsMV4K30M&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Topmate: &lt;a href="https://topmate.io/subrata" rel="noopener noreferrer"&gt;https://topmate.io/subrata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React Native Mastery: &lt;a href="https://rnm.subraatakumar.com/" rel="noopener noreferrer"&gt;https://rnm.subraatakumar.com/&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnativemastery</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>The Phantom in the Sandbox: Architecting an Offline AI Coach with React Native and Gemma 4</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Wed, 03 Jun 2026 03:06:07 +0000</pubDate>
      <link>https://dev.to/subraatakumar/the-phantom-in-the-sandbox-architecting-an-offline-ai-coach-with-react-native-and-gemma-4-4i63</link>
      <guid>https://dev.to/subraatakumar/the-phantom-in-the-sandbox-architecting-an-offline-ai-coach-with-react-native-and-gemma-4-4i63</guid>
      <description>&lt;p&gt;It was 3:14 AM. The silence in the room was absolute, broken only by the hum of my laptop fan. On my desk sat two testing devices: a Xiaomi MI running Android and my daily driver iPhone 15. Both screens were completely black.&lt;/p&gt;

&lt;p&gt;Beside them lay a half-empty glass of flat water. Irony at its finest.&lt;/p&gt;

&lt;p&gt;For the past three weeks, I had been deep in the engineering trenches of a personal side project, trying to pull off a high-wire architectural act: embedding a fully sovereign, 100% offline, conversational AI Hydration Coach directly into the core of my application. No cloud servers. No API gateways. No network latency. And absolutely no monthly token subscriptions bleeding my runway dry.&lt;/p&gt;

&lt;p&gt;The promise was intoxicating. A user could be on an isolated mountain trail with zero cell service, open &lt;strong&gt;Water Tracker with Subra AI&lt;/strong&gt; on &lt;a href="https://apps.apple.com/us/app/water-tracker-with-subra-ai/id6759248297" rel="noopener noreferrer"&gt;iOS&lt;/a&gt; or &lt;a href="https://play.google.com/store/apps/details?id=com.subraatakumar.watertracker" rel="noopener noreferrer"&gt;Android&lt;/a&gt;, ask their coach a question about thermal fluid loss, and receive a deeply contextualized, real-time response.&lt;/p&gt;

&lt;p&gt;But at 3:15 AM, the log stream on my monitor wasn't giving me context. It was spitting a single, devastating error line over and over:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Fatal Exception: libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to map model memory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The app wasn't just crashing; it was suffocating. I had invited an LLM ghost into my React Native sandbox, and it was ravenous for memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 1: The Sovereign Edge Architecture
&lt;/h2&gt;

&lt;p&gt;To understand how I got here, we have to look at the architectural blueprint. Most product teams building GenAI mobile features take the comfortable path: wrapping an &lt;code&gt;axios&lt;/code&gt; fetch request around a remote cloud API endpoint.&lt;/p&gt;

&lt;p&gt;It’s elegant until the user steps into an elevator, a subway tunnel, or an airplane. Then, your "smart" coach reverts to an expensive loading spinner. Worse, every time a user casually chats with your app, &lt;em&gt;you&lt;/em&gt; get billed. If your app goes viral, your API bills scale linearly, threatening to bankrupt your project before monetization even kicks in.&lt;/p&gt;

&lt;p&gt;As a solo indie developer, I wanted a localized architecture. A sovereign edge.&lt;/p&gt;

&lt;p&gt;To pull this off, I needed a highly optimized runtime and a model small enough to fit inside a mobile app's tight memory sandbox, yet smart enough to avoid hallucinating medical advice.&lt;/p&gt;

&lt;p&gt;Enter Google’s newly minted &lt;strong&gt;LiteRT-LM&lt;/strong&gt; stack.&lt;/p&gt;

&lt;p&gt;For the uninitiated, &lt;strong&gt;LiteRT&lt;/strong&gt; (the production-ready framework formerly known as TensorFlow Lite) is the high-performance multi-platform runtime trusted by millions of edge applications. But raw LiteRT handles low-level tensor execution. To build an LLM app, you need an orchestration layer above it to manage Key-Value (KV) caches, enforce prompt templates, handle speculative decoding, and execute function calling. That is exactly what the &lt;a href="https://developers.google.com/edge/litert-lm/overview" rel="noopener noreferrer"&gt;LiteRT-LM Overview&lt;/a&gt; brings to the table.&lt;/p&gt;

&lt;p&gt;And the brain? The &lt;a href="https://developers.google.com/edge/litert-lm/models/gemma-4" rel="noopener noreferrer"&gt;Gemma 4 E2B&lt;/a&gt; model family. Specially built for on-device applications, the E2B variant is a lightweight powerhouse. It packs a text decoder with 0.79GB of weights and 1.12GB of embedding parameters into a ~2.59 GB &lt;code&gt;.litertlm&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;But don't let its size fool you. It supports a staggering &lt;strong&gt;32k context length&lt;/strong&gt; and features &lt;strong&gt;Multi-Token Prediction (MTP)&lt;/strong&gt; drafters natively out of the box, allowing the framework to predict multiple upcoming tokens concurrently for a massive speedup on mobile chips.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 2: The Edge of the Bridge
&lt;/h2&gt;

&lt;p&gt;While community wrappers like &lt;code&gt;react-native-litert-lm&lt;/code&gt; have emerged to bridge these ecosystems, dropping a raw 2.5GB model file into a cross-platform environment is never a plug-and-play affair. To truly understand performance bottlenecks, optimize token-streaming speeds, and prevent memory leaks, you have to look under the hood at how LiteRT-LM binds to the device's native metal.&lt;/p&gt;

&lt;p&gt;The actual implementation maps to raw native development guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Kotlin engine setup: &lt;a href="https://developers.google.com/edge/litert-lm/android" rel="noopener noreferrer"&gt;LiteRT-LM Android Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Swift wrapper orchestration: &lt;a href="https://developers.google.com/edge/litert-lm/swift" rel="noopener noreferrer"&gt;LiteRT-LM Swift Guide&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mission was clear: Initialize a singleton instance of the LiteRT-LM inference engine natively, load the heavy &lt;code&gt;.litertlm&lt;/code&gt; model file into memory once, expose a thread-safe &lt;code&gt;sendMessage&lt;/code&gt; method over the bridge, and stream the generated tokens back to the JavaScript UI in chunks.&lt;/p&gt;

&lt;p&gt;Here is the structural logic of how the native engines map to both platforms to talk back to a cross-platform state layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The iOS Blueprint (Swift)
&lt;/h3&gt;

&lt;p&gt;On iOS, the compiler links against the local LiteRT-LM framework headers, initializing the model and managing the asynchronous stream over an &lt;code&gt;RCTEventEmitter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WaterAIModule.swift&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;LiteRTLM&lt;/span&gt; &lt;span class="c1"&gt;// Under the hood native framework linkage&lt;/span&gt;

&lt;span class="kd"&gt;@objc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;WaterAIModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;WaterAIModule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;RCTEventEmitter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;lmEngine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;currentConversation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Conversation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;

  &lt;span class="kd"&gt;@objc&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;initializeEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolver&lt;/span&gt; &lt;span class="nv"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;@escaping&lt;/span&gt; &lt;span class="kt"&gt;RCTPromiseResolveBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rejecter&lt;/span&gt; &lt;span class="nv"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;@escaping&lt;/span&gt; &lt;span class="kt"&gt;RCTPromiseRejectBlock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;EngineSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// Max out context token space allocated for conversation&lt;/span&gt;
      &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mainExecutorSettings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxNumTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt; 

      &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lmEngine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentConversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lmEngine&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createConversation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ConversationConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;preface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"You are an expert Hydration AI Coach. Keep answers concise, scientific, and highly practical."&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Engine Warm and Ready"&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="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ERR_INIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Failed to awaken LiteRT-LM Engine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;@objc&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;askCoach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentConversation&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;sendEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;withName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"onTokenReceived"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Engine not initialized"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Stream back tokens sequentially to make UI responsive&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;sendEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;withName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"onTokenReceived"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&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="nf"&gt;sendEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;withName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"onTokenReceived"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localizedDescription&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="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;supportedEvents&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="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"onTokenReceived"&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;
  
  
  The Android Blueprint (Kotlin)
&lt;/h3&gt;

&lt;p&gt;On the Android side, the Java Native Interface (JNI) overhead means handling context carefully, passing inputs securely down to the underlying XNNPACK or GPU backends.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WaterAIModule.kt&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.subraatakumar.watertracker&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.modules.core.DeviceEventManagerModule&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.edge.litertlm.Engine&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.edge.litertlm.EngineSettings&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.edge.litertlm.Conversation&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WaterAIModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReactContextBaseJavaModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;lmEngine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;conversation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Conversation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;moduleScope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;SupervisorJob&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"WaterAIModule"&lt;/span&gt;

    &lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;initializeEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EngineSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setModelPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMaxNumTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="n"&gt;lmEngine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lmEngine&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;createConversation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Android Engine Alive"&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="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ERR_ANDROID_INIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localizedMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&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="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;askCoach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;streamConversation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="n"&gt;moduleScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="n"&gt;streamConversation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createMap&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;putString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="n"&gt;reactApplicationContext&lt;/span&gt;
                        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DeviceEventManagerModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RCTDeviceEventEmitter&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"onTokenReceived"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map&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="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Handle stream drop failures cleanly&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;h2&gt;
  
  
  Chapter 3: The 607MB Breakthrough
&lt;/h2&gt;

&lt;p&gt;Back to 3:15 AM. The code looked immaculate, but the app was still imploding on startup.&lt;/p&gt;

&lt;p&gt;The physical math of mobile development is ruthless. A standard mobile application gets allocated anywhere from 200MB to 500MB of resident RAM by the OS before it lands on the high-risk eviction list. My model file alone was 2.59 GB. How was I supposed to squeeze a mountain inside a wallet?&lt;/p&gt;

&lt;p&gt;I poured over the technical specifications of Gemma 4 E2B. That's when I found the missing clue, hidden inside the mechanics of the runtime memory-mapping subsystem.&lt;/p&gt;

&lt;p&gt;LiteRT-LM implements a highly advanced memory footprint optimization strategy: &lt;strong&gt;It splits how it treats model parameters.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemma 4 E2B Model (2.59 GB Total Container)
├── Text Decoder Weights (0.79 GB)  ---&amp;gt; Kept strictly in Resident Physical RAM
└── Embedding Parameters (1.12 GB)  ---&amp;gt; Memory-Mapped (.mmap) dynamically from disk

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

&lt;/div&gt;



&lt;p&gt;Instead of copying the full 2.59 GB binary wholesale into physical RAM blocks, the engine uses weight caching mechanisms (like XNNPACK's native allocations). It pins the critical 0.79GB text decoder directly in execution memory, while memory-mapping the massive embedding layers directly from the device's storage on-demand.&lt;/p&gt;

&lt;p&gt;The physical memory footprint doesn't hit 2.5 GB. It settles beautifully at &lt;strong&gt;just around 607MB to 700MB.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But why was my build still failing?&lt;/p&gt;

&lt;p&gt;Because of &lt;em&gt;how&lt;/em&gt; I packaged the model container. I had manually bundled the raw tokenizer config files and the converted layers together, blinding the engine's memory-mapping parser. It was reading the whole file layout as unaligned, un-mappable raw byte-blobs.&lt;/p&gt;

&lt;p&gt;To fix it, I had to utilize the official serialization architecture outlined in the &lt;a href="https://developers.google.com/edge/litert-lm/file_builder" rel="noopener noreferrer"&gt;LiteRT-LM File Builder Documentation&lt;/a&gt;. The builder aligns the internal headers perfectly so the mobile OS can execute memory mapping with zero block overhead.&lt;/p&gt;

&lt;p&gt;I spun up a Python virtual environment and ran the compiler pipeline script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;litert-lm-builder

litert-lm-builder &lt;span class="se"&gt;\&lt;/span&gt;
  output &lt;span class="nt"&gt;--path&lt;/span&gt; ./assets/gemma-4-E2B-hydra.litertlm &lt;span class="se"&gt;\&lt;/span&gt;
  system_metadata &lt;span class="nt"&gt;--str&lt;/span&gt; engine_target &lt;span class="s2"&gt;"mobile-edge"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  llm_metadata &lt;span class="nt"&gt;--path&lt;/span&gt; ./configs/gemma_policy.pb &lt;span class="se"&gt;\&lt;/span&gt;
  tflite_model &lt;span class="nt"&gt;--path&lt;/span&gt; ./models/prefill_decode.tflite &lt;span class="nt"&gt;--model_type&lt;/span&gt; prefill_decode &lt;span class="nt"&gt;--backend_constraint&lt;/span&gt; gpu &lt;span class="se"&gt;\&lt;/span&gt;
  hf_tokenizer &lt;span class="nt"&gt;--path&lt;/span&gt; ./tokenizer/tokenizer.json

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

&lt;/div&gt;



&lt;p&gt;The script ran cleanly, packaging the binary layers while injecting explicit alignment offsets into the file structure. I dragged the brand-new, optimized &lt;code&gt;gemma-4-E2B-hydra.litertlm&lt;/code&gt; file into the app bundles.&lt;/p&gt;

&lt;p&gt;I hit rebuild.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 4: It Listens, It Thinks, It Adapts
&lt;/h2&gt;

&lt;p&gt;The compilation finished. I tapped the chat icon on the app screen. The interface faded into a clean, minimalist prompt box.&lt;/p&gt;

&lt;p&gt;I typed: &lt;em&gt;"I just finished a 5K run in 85-degree humid weather. I’ve had 500ml of water today. Am I at risk?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I held my breath, waiting for the dreaded native crash log.&lt;/p&gt;

&lt;p&gt;The monitor remained clear. Instead, token by token, words started cascading onto the mobile viewport with fluid speed—hitting nearly &lt;strong&gt;50 tokens per second&lt;/strong&gt; accelerated entirely by the local device's GPU layers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Thinking...] 
User hydration state is dangerously low given thermal conditions. 
Prefill tokens: 1024 | Decode: ~52 tok/sec.

"You are experiencing significant net fluid deficit. At 85°F with high humidity, 
your sweat rate can easily exceed 1L/hour. Consuming only 500ml puts you in an 
acute state of dehydration. Skip pure water for the next 300ml—you need 
isotonic electrolytes immediately to restore plasma volume."

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

&lt;/div&gt;



&lt;p&gt;No remote servers were pinged. No user tracking data escaped into the cloud. It was completely secure, private, instantaneous intelligence running locally on a handheld piece of glass.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Takeaway: The Stack of 2030 is On-Device
&lt;/h2&gt;

&lt;p&gt;Building intelligence at the edge forces you to shed the lazy habits of cloud-first development. You cannot throw infinite elastic computing resources at a bad algorithm or a bloated architectural layout when your execution limits are hard-capped by a lithium-ion battery and a mobile operating system's kernel.&lt;/p&gt;

&lt;p&gt;But the reward? True application autonomy for a side project without ongoing maintenance costs.&lt;/p&gt;

&lt;p&gt;If you want to experience how this architecture behaves in production under real-world constraints, you can test the implementation live on both modern ecosystems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the iOS live build: &lt;a href="https://apps.apple.com/us/app/water-tracker-with-subra-ai/id6759248297" rel="noopener noreferrer"&gt;Water Tracker with Subra AI on the App Store&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download the Android live build: &lt;a href="https://play.google.com/store/apps/details?id=com.subraatakumar.watertracker" rel="noopener noreferrer"&gt;Water Tracker Engine on Google Play&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The era of writing simple wrapper apps around expensive cloud endpoints is winding down. By bridging native frameworks like LiteRT-LM into accessible cross-platform viewports like React Native, we aren't just shipping apps—we're deploying highly optimized, self-contained digital minds directly into our users' pockets.&lt;/p&gt;

&lt;p&gt;And the best part? The next time my cloud server goes down... my users will still be perfectly hydrated.&lt;/p&gt;




&lt;h3&gt;
  
  
  Technical Reference Ledger &amp;amp; Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Model Architecture:&lt;/strong&gt; &lt;a href="https://developers.google.com/edge/litert-lm/models/gemma-4" rel="noopener noreferrer"&gt;Gemma 4 LiteRT-LM Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Core Specifications:&lt;/strong&gt; &lt;a href="https://developers.google.com/edge/litert-lm/overview" rel="noopener noreferrer"&gt;LiteRT-LM Core Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android JNI Implementation Matrix:&lt;/strong&gt; &lt;a href="https://developers.google.com/edge/litert-lm/android" rel="noopener noreferrer"&gt;LiteRT-LM Android Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iOS Metal Acceleration Layer:&lt;/strong&gt; &lt;a href="https://developers.google.com/edge/litert-lm/swift" rel="noopener noreferrer"&gt;LiteRT-LM Swift Framework&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Binary Alignment Utility:&lt;/strong&gt; &lt;a href="https://developers.google.com/edge/litert-lm/file_builder" rel="noopener noreferrer"&gt;LiteRT-LM File Builder CLI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>gemmachallenge</category>
      <category>programming</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Stop Shipping 20 Locale Files in React Native: On-Device Translation for Dynamic Language Packs</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Tue, 02 Jun 2026 09:41:36 +0000</pubDate>
      <link>https://dev.to/subraatakumar/stop-shipping-20-locale-files-in-react-native-on-device-translation-for-dynamic-language-packs-k2o</link>
      <guid>https://dev.to/subraatakumar/stop-shipping-20-locale-files-in-react-native-on-device-translation-for-dynamic-language-packs-k2o</guid>
      <description>&lt;h1&gt;
  
  
  Stop Shipping 20 Locale Files in React Native: On-Device Translation for Dynamic Language Packs
&lt;/h1&gt;

&lt;p&gt;Internationalization in mobile apps usually starts clean and then gets expensive.&lt;/p&gt;

&lt;p&gt;At first, you keep a couple of JSON files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;en.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;es.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fr.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That works when your product is small and the set of languages is stable.&lt;/p&gt;

&lt;p&gt;It breaks down when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you want to support many languages&lt;/li&gt;
&lt;li&gt;the product team keeps changing copy&lt;/li&gt;
&lt;li&gt;translated files drift out of sync&lt;/li&gt;
&lt;li&gt;some languages are only partially used&lt;/li&gt;
&lt;li&gt;you do not want to run every string through a server-side translation pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the problem &lt;code&gt;@tcbs/react-native-language-translator&lt;/code&gt; is trying to solve.&lt;/p&gt;

&lt;p&gt;It lets a React Native app keep a source language, translate missing keys on device, and cache the generated language pack locally.&lt;/p&gt;

&lt;p&gt;Package: &lt;a href="https://www.npmjs.com/package/@tcbs/react-native-language-translator" rel="noopener noreferrer"&gt;@tcbs/react-native-language-translator&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You can see the same idea live in the Water Tracker app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iOS: &lt;a href="https://apps.apple.com/us/app/water-tracker-with-subra-ai/id6759248297" rel="noopener noreferrer"&gt;Water Tracker with Subra AI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Android: &lt;a href="https://play.google.com/store/apps/details?id=com.subraatakumar.watertracker" rel="noopener noreferrer"&gt;Water Tracker on Google Play&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Many React Native apps treat localization as a static asset problem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;keep one JSON file per language&lt;/li&gt;
&lt;li&gt;ship all of them in the app&lt;/li&gt;
&lt;li&gt;update all of them whenever English changes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That model has real costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Translation files become operational debt
&lt;/h3&gt;

&lt;p&gt;Every new feature adds more keys. Every copy change forces translators to update multiple locale files. Over time, the translation layer becomes a maintenance queue.&lt;/p&gt;

&lt;p&gt;The result is predictable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing keys&lt;/li&gt;
&lt;li&gt;stale translations&lt;/li&gt;
&lt;li&gt;untranslated fallback strings&lt;/li&gt;
&lt;li&gt;inconsistent release quality across languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Shipping many locales is wasteful
&lt;/h3&gt;

&lt;p&gt;Most users only need one target language. But many apps ship every locale anyway. That increases bundle size and creates a lot of dead weight for users who will never use most of those files.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dynamic product copy is hard to localize well
&lt;/h3&gt;

&lt;p&gt;If your app changes quickly, static translation files lag behind. Teams either accept stale translations or build a backend workflow to keep everything synchronized.&lt;/p&gt;

&lt;p&gt;That is often more infrastructure than the app actually needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Server-side translation is not always the right tradeoff
&lt;/h3&gt;

&lt;p&gt;Calling a translation API at runtime introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;API cost&lt;/li&gt;
&lt;li&gt;network dependency&lt;/li&gt;
&lt;li&gt;privacy considerations&lt;/li&gt;
&lt;li&gt;offline failure modes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For some apps, that is acceptable. For many mobile flows, it is not.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea behind the package
&lt;/h2&gt;

&lt;p&gt;Instead of treating every target language as a fully prebuilt asset, this package treats translation as a local capability.&lt;/p&gt;

&lt;p&gt;The app keeps one source dictionary, typically English, and then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;detects the user’s target language&lt;/li&gt;
&lt;li&gt;checks whether that language is supported&lt;/li&gt;
&lt;li&gt;downloads the native translation model for the language pair&lt;/li&gt;
&lt;li&gt;translates missing keys on device&lt;/li&gt;
&lt;li&gt;stores the translated values locally&lt;/li&gt;
&lt;li&gt;applies the cached values to the app’s i18n layer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That changes the architecture in a useful way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the source language stays canonical&lt;/li&gt;
&lt;li&gt;target languages are generated incrementally&lt;/li&gt;
&lt;li&gt;only needed translations are downloaded and cached&lt;/li&gt;
&lt;li&gt;the app can improve coverage over time without shipping every locale file up front&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What solution is it providing?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@tcbs/react-native-language-translator&lt;/code&gt; provides three things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A React Native native bridge for on-device translation
&lt;/h3&gt;

&lt;p&gt;The package exposes a native translator module for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android via Google ML Kit Translate&lt;/li&gt;
&lt;li&gt;iOS via ML Kit Translate through the native bridge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives JavaScript code a simple interface for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checking supported language pairs&lt;/li&gt;
&lt;li&gt;preparing language models&lt;/li&gt;
&lt;li&gt;translating batches of strings&lt;/li&gt;
&lt;li&gt;reading downloaded languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. A supported language catalog
&lt;/h3&gt;

&lt;p&gt;The package includes a ready-to-use supported languages list for building UI such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;language pickers&lt;/li&gt;
&lt;li&gt;onboarding preference screens&lt;/li&gt;
&lt;li&gt;settings pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each entry contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;language code&lt;/li&gt;
&lt;li&gt;display name&lt;/li&gt;
&lt;li&gt;flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also includes a small alias normalization layer, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hn -&amp;gt; hi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;od -&amp;gt; or&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters because app-internal language codes and translator-supported codes do not always match cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A language-pack generation workflow
&lt;/h3&gt;

&lt;p&gt;This is the more interesting part.&lt;/p&gt;

&lt;p&gt;The package does not only translate text. It helps build a practical runtime flow around translation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flatten a source dictionary&lt;/li&gt;
&lt;li&gt;compare it with cached and bundled translations&lt;/li&gt;
&lt;li&gt;identify missing keys&lt;/li&gt;
&lt;li&gt;translate only the missing values&lt;/li&gt;
&lt;li&gt;save them into a repository abstraction&lt;/li&gt;
&lt;li&gt;apply them back into your i18n resource bundle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That turns translation from a one-off API call into a reusable app pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  How is it providing that solution?
&lt;/h2&gt;

&lt;p&gt;The package is opinionated in a useful way: it separates the translation engine from your app’s storage and i18n implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Native translation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;createNativeTranslatorModule()&lt;/code&gt; API exposes methods such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getSupportedLanguages()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getDownloadedLanguages()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isSupported(source, target)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prepareLanguagePair(source, target)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;translateBatch(texts, source, target)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the lowest-level layer. It is responsible for native translation model setup and translation execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Language code normalization
&lt;/h3&gt;

&lt;p&gt;The package normalizes language tags and resolves aliases before calling the native layer.&lt;/p&gt;

&lt;p&gt;This helps when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your app uses short internal aliases&lt;/li&gt;
&lt;li&gt;user profile data stores non-standard codes&lt;/li&gt;
&lt;li&gt;upstream systems do not agree on locale naming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It reduces friction between app-specific language identifiers and translator-supported codes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Coverage-based language pack generation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ensureLanguagePackReady()&lt;/code&gt; helper does most of the workflow orchestration.&lt;/p&gt;

&lt;p&gt;Conceptually, it does this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;flatten the source dictionary&lt;/li&gt;
&lt;li&gt;read existing cached translations&lt;/li&gt;
&lt;li&gt;inspect the currently bundled translations&lt;/li&gt;
&lt;li&gt;calculate what is missing or still effectively untranslated&lt;/li&gt;
&lt;li&gt;prepare the language pair&lt;/li&gt;
&lt;li&gt;translate missing values in chunks&lt;/li&gt;
&lt;li&gt;persist generated translations&lt;/li&gt;
&lt;li&gt;return coverage information&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This design matters because production localization is not binary. It is not just “translated” or “not translated.” You need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how many keys exist&lt;/li&gt;
&lt;li&gt;how many are ready&lt;/li&gt;
&lt;li&gt;how many are still missing&lt;/li&gt;
&lt;li&gt;how many are still identical to source text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The package exposes that coverage model directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Storage-agnostic integration
&lt;/h3&gt;

&lt;p&gt;The package does not force a database choice.&lt;/p&gt;

&lt;p&gt;Instead, you provide a repository adapter with methods like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getMapForLanguage()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upsertMany()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means you can back it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;li&gt;Realm&lt;/li&gt;
&lt;li&gt;MMKV-backed structured persistence&lt;/li&gt;
&lt;li&gt;any custom local store&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same pattern applies to your i18n layer. You provide an adapter with methods such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getResourceBundle()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addResourceBundle()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the package can work with your existing localization setup rather than replacing it.&lt;/p&gt;




&lt;h2&gt;
  
  
  How many languages does it support?
&lt;/h2&gt;

&lt;p&gt;The current package exports &lt;strong&gt;59 supported languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;English&lt;/li&gt;
&lt;li&gt;Spanish&lt;/li&gt;
&lt;li&gt;French&lt;/li&gt;
&lt;li&gt;German&lt;/li&gt;
&lt;li&gt;Arabic&lt;/li&gt;
&lt;li&gt;Hindi&lt;/li&gt;
&lt;li&gt;Bengali&lt;/li&gt;
&lt;li&gt;Gujarati&lt;/li&gt;
&lt;li&gt;Tamil&lt;/li&gt;
&lt;li&gt;Telugu&lt;/li&gt;
&lt;li&gt;Japanese&lt;/li&gt;
&lt;li&gt;Korean&lt;/li&gt;
&lt;li&gt;Chinese&lt;/li&gt;
&lt;li&gt;Russian&lt;/li&gt;
&lt;li&gt;Portuguese&lt;/li&gt;
&lt;li&gt;Turkish&lt;/li&gt;
&lt;li&gt;Ukrainian&lt;/li&gt;
&lt;li&gt;Vietnamese&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full list is available directly from the package through &lt;code&gt;supportedLanguages&lt;/code&gt; and &lt;code&gt;getSupportedLanguages()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is enough to cover a broad set of global product scenarios while keeping the app-side integration simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this approach is useful
&lt;/h2&gt;

&lt;p&gt;There is a practical middle ground between “ship every locale file forever” and “call a translation API on every screen.”&lt;/p&gt;

&lt;p&gt;This package sits in that middle ground.&lt;/p&gt;

&lt;h3&gt;
  
  
  It reduces translation maintenance pressure
&lt;/h3&gt;

&lt;p&gt;You still keep a canonical source dictionary, but you do not need every target language file to be complete before the app can function.&lt;/p&gt;

&lt;h3&gt;
  
  
  It keeps the app responsive to copy changes
&lt;/h3&gt;

&lt;p&gt;If new English keys appear, the app can generate and cache missing translated entries instead of waiting for a full manual localization cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  It works with offline-first thinking better than API translation
&lt;/h3&gt;

&lt;p&gt;Once models and translations are downloaded, the app can reuse them locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  It avoids forcing a backend translation service
&lt;/h3&gt;

&lt;p&gt;That can be useful for teams that want fewer moving parts or tighter privacy boundaries around runtime text handling.&lt;/p&gt;




&lt;h2&gt;
  
  
  A realistic usage example
&lt;/h2&gt;

&lt;p&gt;Here is the simple path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createNativeTranslatorModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getSupportedLanguages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isLanguageSupported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resolveTranslatorLanguageCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tcbs/react-native-language-translator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;od&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolveTranslatorLanguageCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedLanguage&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="nf"&gt;isLanguageSupported&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetLanguage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unsupported language&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;languageOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getSupportedLanguages&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;includeEnglish&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeTranslatorModule&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;translator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepareLanguagePair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetLanguage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translated&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;translator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translateBatch&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="s1"&gt;Settings&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="s1"&gt;Store&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="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;targetLanguage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is useful if you only need direct string translation.&lt;/p&gt;

&lt;p&gt;But the more production-ready pattern is language-pack generation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;applyCachedLanguagePack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createNativeTranslatorModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ensureLanguagePackReady&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tcbs/react-native-language-translator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ensureLanguagePackReady&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;sourceLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;targetLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selectedCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sourceDictionary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;enJson&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localizedOverrideRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;nativeModule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createNativeTranslatorModule&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;applyCachedLanguagePack&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;languageCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selectedCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localizedOverrideRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the package becomes more than a translator wrapper. It becomes infrastructure for a dynamic localization workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  What teams should know before using it
&lt;/h2&gt;

&lt;p&gt;This is not magic. There are still operational realities.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Translation models are runtime assets
&lt;/h3&gt;

&lt;p&gt;Models need to be downloaded for the language pair. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first use can take time&lt;/li&gt;
&lt;li&gt;network availability matters during preparation&lt;/li&gt;
&lt;li&gt;you should show clear user-facing progress states&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Generated translations should be treated as cached output
&lt;/h3&gt;

&lt;p&gt;You should think of generated language packs as local derived data, not as your source of truth.&lt;/p&gt;

&lt;p&gt;The source dictionary remains your canonical content.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Quality expectations should be explicit
&lt;/h3&gt;

&lt;p&gt;On-device translation is useful, but you still need product judgment.&lt;/p&gt;

&lt;p&gt;For critical legal, medical, financial, or brand-sensitive copy, human review may still be necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Good UX matters
&lt;/h3&gt;

&lt;p&gt;If you adopt this approach, the app should explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;that language resources may need downloading&lt;/li&gt;
&lt;li&gt;that translation happens on device&lt;/li&gt;
&lt;li&gt;that results are cached locally&lt;/li&gt;
&lt;li&gt;that some screens may improve in coverage over time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where this package fits best
&lt;/h2&gt;

&lt;p&gt;This approach is especially useful for apps that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ship fast and change copy often&lt;/li&gt;
&lt;li&gt;want broad language reach without shipping many static locale files&lt;/li&gt;
&lt;li&gt;want local generation and local caching&lt;/li&gt;
&lt;li&gt;already have an i18n setup and just need a translation generation layer&lt;/li&gt;
&lt;li&gt;want to avoid a runtime translation backend for common flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is less ideal if your localization model requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formally reviewed translations for every string before release&lt;/li&gt;
&lt;li&gt;a centralized translation management system as the only allowed source&lt;/li&gt;
&lt;li&gt;strict server-mediated copy governance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final take
&lt;/h2&gt;

&lt;p&gt;The interesting part of &lt;code&gt;@tcbs/react-native-language-translator&lt;/code&gt; is not just that it translates strings.&lt;/p&gt;

&lt;p&gt;It provides a workable architecture for dynamic localization in React Native:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;source language as canonical input&lt;/li&gt;
&lt;li&gt;native on-device translation as the engine&lt;/li&gt;
&lt;li&gt;cached language packs as local derived output&lt;/li&gt;
&lt;li&gt;coverage-aware helpers to manage completeness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a practical model for teams that want broader language support without turning localization into a backend-heavy system.&lt;/p&gt;

&lt;p&gt;If you want to try it, the package is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@tcbs/react-native-language-translator" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@tcbs/react-native-language-translator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>subrata</category>
      <category>reactnativemastery</category>
    </item>
    <item>
      <title>The Death of the React Native Bridge: Moving from JSON to JSI in 2026</title>
      <dc:creator>Subrata Kumar Das</dc:creator>
      <pubDate>Sat, 30 May 2026 07:37:25 +0000</pubDate>
      <link>https://dev.to/subraatakumar/the-death-of-the-react-native-bridge-moving-from-json-to-jsi-in-2026-2614</link>
      <guid>https://dev.to/subraatakumar/the-death-of-the-react-native-bridge-moving-from-json-to-jsi-in-2026-2614</guid>
      <description>&lt;h2&gt;
  
  
  What is the Native Bridge?
&lt;/h2&gt;

&lt;p&gt;The React Native Bridge is a communication layer that allows the JavaScript thread and the Native threads (iOS/Android) to talk to each other.&lt;br&gt;
Because JavaScript and native languages (like Swift, Objective-C, Java, or Kotlin) cannot communicate directly, they require a middleman. The Bridge functions as a message broker.  &lt;/p&gt;
&lt;h2&gt;
  
  
  How it works:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Serialization: JavaScript converts actions or data into JSON strings.&lt;/li&gt;
&lt;li&gt;Asynchronous Transport: The JSON payload is sent asynchronously across the bridge.&lt;/li&gt;
&lt;li&gt;Deserialization: The native side decodes the JSON and executes the requested platform action (e.g., rendering a view or accessing hardware).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  When is a Native Bridge Required?
&lt;/h2&gt;

&lt;p&gt;By default, React Native handles everyday components (like  or ) and APIs automatically. However, you must manually create a custom native bridge (via Native Modules or Native UI Components) in the following scenarios:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing Unsupported Hardware: When you need device features lacking a built-in React Native API—such as an advanced camera sensor, biometrics (FaceID/Fingerprint), or custom Bluetooth peripherals.
&lt;/li&gt;
&lt;li&gt;Integrating Third-Party Native SDKs: When a service provider (like a payment gateway, analytics tool, or advertisement network) only gives you an iOS CocoaPod or an Android Gradle dependency.
&lt;/li&gt;
&lt;li&gt;Reusing Existing Native Code: When you are migrating an older native app to React Native and want to salvage functional Kotlin, Swift, or Objective-C business logic.
&lt;/li&gt;
&lt;li&gt;High-Performance Heavy Lifting: When executing intensive tasks—like image processing, audio manipulation, or complex database operations—that would otherwise freeze the single-threaded JavaScript environment. &lt;/li&gt;
&lt;li&gt;Custom UI Renders: When incorporating a platform-specific UI layout that cannot be fully built using React Native's standard cross-platform components.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Important Architectural Note
&lt;/h2&gt;

&lt;p&gt;React Native heavily transitioned away from this legacy asynchronous Bridge.&lt;br&gt;&lt;br&gt;
The newer framework versions standardise the New Architecture, swapping out the JSON bridge for the JavaScript Interface (JSI). JSI allows JavaScript to hold direct C++ memory references to native methods. This shift unlocks synchronous execution and completely eliminates JSON serialization delays, solving historic performance bottlenecks. Instead of creating old "bridges", you will typically now build TurboModules and Fabric Components. &lt;br&gt;
Are you planning to build a custom native module for a specific device feature, or are you troubleshooting a performance bottleneck in your current app? Let me know in the comments.&lt;/p&gt;

&lt;p&gt;The transition away from the old JSON native bridge to JSI (JavaScript Interface) happened as a gradual rollout over several years.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Transition Timeline
&lt;/h2&gt;
&lt;h2&gt;
  
  
  1. When did React Native move to JSI?
&lt;/h2&gt;

&lt;p&gt;The transition to JSI began experimentally in March 2022 with the release of React Native 0.68. This release introduced the very first pillars of the New Architecture (TurboModules and the Fabric renderer), which relied on JSI rather than the old asynchronous bridge. &lt;/p&gt;
&lt;h2&gt;
  
  
  2. To which version was the Native Bridge supported?
&lt;/h2&gt;

&lt;p&gt;The old bridge framework was supported as the primary, default engine up through React Native 0.75. Here is how the deprecation and complete removal unfolded:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native 0.76 (October 2024): The New Architecture (JSI-powered) became the default for all new projects. An interoperability layer still existed, allowing legacy bridge-based modules to function via a temporary compatibility shim. &lt;/li&gt;
&lt;li&gt;React Native 0.82 (October 2025): The legacy architecture was permanently disabled. Developers lost the ability to opt out of the New Architecture via flags (newArchEnabled=false was removed). &lt;/li&gt;
&lt;li&gt;React Native 0.85 (April 2026): The legacy bridge code was removed from the codebase entirely. There is no longer a fallback mechanism or bridge interoperability layer.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Architectural Milestone Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;React Native Version&lt;/th&gt;
&lt;th&gt;Release Date&lt;/th&gt;
&lt;th&gt;Bridge &amp;amp; JSI Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.68&lt;/td&gt;
&lt;td&gt;March 2022&lt;/td&gt;
&lt;td&gt;JSI Introduced: Experimental opt-in for the New Architecture.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.73&lt;/td&gt;
&lt;td&gt;Late 2023&lt;/td&gt;
&lt;td&gt;Bridgeless Mode: Introduced as an experimental opt-in.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.76&lt;/td&gt;
&lt;td&gt;October 2024&lt;/td&gt;
&lt;td&gt;Default Shift: JSI / New Architecture turned on by default. Old bridge moved to an interop layer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.82&lt;/td&gt;
&lt;td&gt;October 2025&lt;/td&gt;
&lt;td&gt;Old Architecture Disabled: Toggle flags removed; New Architecture mandatory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;April 2026&lt;/td&gt;
&lt;td&gt;Complete Removal: The legacy bridge code is entirely deleted.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Starting in React Native 0.85, you can no longer use the old, asynchronous JSON native bridge. The legacy bridge code has been completely removed from the framework's core repository.&lt;br&gt;&lt;br&gt;
However, this does not mean you can no longer write custom native code. It just means the mechanism has completely changed.  &lt;/p&gt;
&lt;h2&gt;
  
  
  What is Gone vs. What Replaces It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;❌ What you cannot do anymore: You can no longer use RCTBridgeModule (iOS) or ReactContextBaseJavaModule (Android) to pass serialized JSON data back and forth asynchronously. The "interop layer" that let these old modules run on newer versions has been fully deleted.
&lt;/li&gt;
&lt;li&gt;✅ What you must do instead: You must write Turbo Native Modules and Fabric Components. They achieve the exact same goal (allowing JavaScript to trigger native code) but use JSI to call C++ functions directly, providing instant, synchronous execution without JSON serialization.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Practical Impact
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;For App Developers: If your project targets React Native 0.85, any internal native code you previously wrote using the old bridge format must be rewritten into TurboModules. &lt;/li&gt;
&lt;li&gt;For Third-Party Libraries: Any community npm package that has not updated its code to support the New Architecture will break or crash your build immediately in 0.85. &lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  🚀 Why Learning the React Native JSON Bridge Still Matters in 2026
&lt;/h2&gt;

&lt;p&gt;Learning the legacy JSON bridge is incredibly valuable because it teaches you the fundamental, underlying mechanics of how cross-platform frameworks handle inter-process communication (IPC).&lt;br&gt;
Even as modern frameworks transition to zero-latency, direct-memory solutions like the JavaScript Interface (JSI), mastering the bridge gives you a deep, conceptual understanding of data serialization, asynchronous thread management, and the architectural trade-offs inherent in decoupling user interfaces from native operating systems.&lt;br&gt;
Furthermore, the vast majority of enterprise-level React Native applications currently running in production were built over the last decade and still rely heavily on legacy bridge systems. By knowing how the bridge operates, you instantly become a highly competitive engineer capable of maintaining, troubleshooting, and strategically migrating massive, real-world codebases to newer architectures.&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ Step-by-Step Tutorial: Building Your First JSON Native Bridge
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will build a custom native module that performs a simple arithmetic addition on the native side (Android and iOS) and returns the result back to JavaScript. This will give you a clear, hands-on understanding of how data flows across the legacy JSON bridge.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: Initialize a Bridge-Compatible React Native App
&lt;/h2&gt;

&lt;p&gt;Because modern versions of React Native disable the legacy bridge by default, we need to explicitly initialize our project using React Native 0.75.4.&lt;br&gt;
Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @react-native-community/cli@latest init JsonBridgeDemo &lt;span class="nt"&gt;--version&lt;/span&gt; 0.75.4
&lt;span class="nb"&gt;cd &lt;/span&gt;JsonBridgeDemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

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

&lt;h2&gt;
  
  
  Turn Off the New Architecture Flags
&lt;/h2&gt;

&lt;p&gt;To ensure the application uses the JSON bridge as its primary engine, verify that the following flags are set to false.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Android: Open android/gradle.properties and confirm this line:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;newArchEnabled=false&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For iOS: Open your terminal, navigate to the ios directory, and install dependencies with the legacy architecture flag:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;cd ios&lt;br&gt;
RCT_NEW_ARCH_ENABLED=0 bundle exec pod install&lt;br&gt;
cd ..&lt;/p&gt;

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

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


&lt;h2&gt;
  
  
  Step 2: Create the Android Native Bridge (Java)
&lt;/h2&gt;

&lt;p&gt;We need two files on the Android side: a Module file (to define our addition logic) and a Package file (to register the module with React Native).&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Create the Module File
&lt;/h2&gt;

&lt;p&gt;Navigate to android/app/src/main/java/com/jsonbridgedemo/ and create a new file named CalculatorModule.java. Paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.jsonbridgedemo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactContextBaseJavaModule&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactMethod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.Callback&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ReactContextBaseJavaModule&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor required by React Native&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt; &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// This defines the name used to import the module in JavaScript&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"CalculatorModule"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// The @ReactMethod annotation exposes this method to the JSON Bridge&lt;/span&gt;
    &lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Callback&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Data is serialized into a JSON format and sent back via the callback&lt;/span&gt;
        &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create the Package File
&lt;/h2&gt;

&lt;p&gt;In the same directory, create a file named CalculatorPackage.java to register your module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.jsonbridgedemo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.ReactPackage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.NativeModule&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.uimanager.ViewManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Collections&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorPackage&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ReactPackage&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ViewManager&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createViewManagers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt; &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NativeModule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createNativeModules&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt; &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NativeModule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;modules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Add our custom module to the bundle list&lt;/span&gt;
        &lt;span class="n"&gt;modules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;modules&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Register the Package
&lt;/h2&gt;

&lt;p&gt;Navigate to android/app/src/main/java/com/jsonbridgedemo/MainApplication.kt. Locate the getPackages() function and register your Java package like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPackages&lt;/span&gt;&lt;span class="o"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ReactPackage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="nc"&gt;PackageList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// Packages that cannot be autolinked yet can be added manually here, for example:&lt;/span&gt;
              &lt;span class="c1"&gt;// add(MyReactNativePackage())&lt;/span&gt;
              &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CalculatorPackage&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 👈 Add this line to register your Java package!&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Because of interoperability, Kotlin initializes CalculatorPackage() exactly as if it were a native Kotlin class.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Create the iOS Native Bridge (Objective-C)
&lt;/h2&gt;

&lt;p&gt;On iOS, we use Objective-C macros provided by React Native to automatically bind our class and methods to the bridge.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create the Header File
&lt;/h2&gt;

&lt;p&gt;Open your project in Xcode, or navigate to the ios/JsonBridgeDemo/ directory and create a file named CalculatorModule.h:&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="cp"&gt;#import &amp;lt;React/RCTBridgeModule.h&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NSObject&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RCTBridgeModule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create the Implementation File
&lt;/h2&gt;

&lt;p&gt;In the same directory, create a file named CalculatorModule.m and add the following code:&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="cp"&gt;#import "CalculatorModule.h"
#import &amp;lt;React/RCTLog.h&amp;gt;
&lt;/span&gt;&lt;span class="k"&gt;@implementation&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;
&lt;span class="c1"&gt;// This macro exports the module to the JavaScript side under the class name&lt;/span&gt;
&lt;span class="n"&gt;RCT_EXPORT_MODULE&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// This macro explicitly exposes the method to the JSON bridge asynchronously&lt;/span&gt;
&lt;span class="n"&gt;RCT_EXPORT_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addNumbers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSInteger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSInteger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RCTResponseSenderBlock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;NSInteger&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// The result is serialized to a JSON payload and returned through the bridge&lt;/span&gt;
    &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(@[&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Link Your Files in Xcode (Crucial Step!)
&lt;/h2&gt;

&lt;p&gt;Unlike Android, you don't need to manually register your iOS module in an implementation file like AppDelegate.mm. React Native’s RCT_EXPORT_MODULE() macro registers it automatically during compilation.&lt;br&gt;
However, Xcode must be explicitly told that these new files exist, or it will skip compiling them entirely. Follow these quick steps to link them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your project's iOS workspace (ios/JsonBridgeDemo.xcworkspace) inside Xcode.&lt;/li&gt;
&lt;li&gt;Right-click on your main project folder (JsonBridgeDemo) in the left-hand sidebar file navigator.&lt;/li&gt;
&lt;li&gt;Click Add Files to "JsonBridgeDemo"...&lt;/li&gt;
&lt;li&gt;Select both CalculatorModule.h and CalculatorModule.m from your project folder.&lt;/li&gt;
&lt;li&gt;A modal configuration sheet will drop down. Set the options precisely like this:&lt;/li&gt;
&lt;li&gt;Action: Select Reference files in place. (This ensures Xcode reads the exact files in your workspace, allowing you to edit them seamlessly in VS Code).

&lt;ul&gt;
&lt;li&gt;Targets: Explicitly Check [✓] the box next to your main application target JsonBridgeDemo. Leave the test target unchecked.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click Finish.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now Xcode knows exactly where your module is, and it will bundle your custom Objective-C code right into the application when you build it!&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 4: Call the Native Bridge from JavaScript
&lt;/h2&gt;

&lt;p&gt;Now that both native platforms have implemented the CalculatorModule, we can consume it in our application UI.&lt;br&gt;
Open your root App.tsx (or App.js) file, replace its contents with the code block below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&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;TextInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NativeModules&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Extract our custom module from the NativeModules bridge registry&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;CalculatorModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NativeModules&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNumber1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNumber2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleCalculate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Triggering the asynchronous native method across the JSON bridge&lt;/span&gt;
    &lt;span class="nx"&gt;CalculatorModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;nativeResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Receives the deserialized JSON response here on the JS side&lt;/span&gt;
      &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nativeResult&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;JSON Bridge Calculator&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextInput&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"numeric"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setNumber1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plus&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextInput&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"numeric"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setNumber2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Calculate on Native Side"&lt;/span&gt; &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleCalculate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resultText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Result from Native: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&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="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f5fcff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;marginBottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderWidth&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="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;marginVertical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;resultText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Run and Test the App
&lt;/h2&gt;

&lt;p&gt;Boot up your bundler and launch the application on your desired test environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To run on Android:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;npx react-native run-android&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To run on iOS:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;npx react-native run-ios&lt;/p&gt;

&lt;h2&gt;
  
  
  When you enter two numbers and tap the button, the numbers are serialized into a JSON payload, passed asynchronously through the native bridge to the OS threads, processed by the platform language, and safely passed back to update your React state!
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  📂 Get the Full Source Code
&lt;/h2&gt;

&lt;p&gt;Want to skip the manual file configuration and see the complete working project immediately? I have uploaded the entire sandbox—including both the Java (Android) and Objective-C (iOS) bridge modules alongside the interactive React Native UI—to GitHub.&lt;/p&gt;

&lt;p&gt;Feel free to clone it, explore the exact file organization we discussed, and use it as a reference playground for your own practice!&lt;/p&gt;

&lt;p&gt;👉 View the Complete JSON Bridge Sandbox on GitHubQuick Start with the Repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com
&lt;span class="nb"&gt;cd &lt;/span&gt;react-native-json-bridge-demo

&lt;span class="c"&gt;# Install JS dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Run on Android&lt;/span&gt;
npx react-native run-android

&lt;span class="c"&gt;# Run on iOS&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;RCT_NEW_ARCH_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 bundle &lt;span class="nb"&gt;exec &lt;/span&gt;pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
npx react-native run-ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Moving to the Future: Building Your First JSI / TurboModule Sandbox
&lt;/h2&gt;

&lt;p&gt;Now that we have mastered how the legacy JSON bridge works, it is time to look forward. In modern React Native (versions 0.76 and newer), the asynchronous JSON bridge is replaced entirely by the JavaScript Interface (JSI).&lt;/p&gt;

&lt;p&gt;With JSI, JavaScript references native C++ methods directly in memory. There is no JSON stringification, no message queuing, and execution is entirely synchronous. Instead of "native bridges", we now write Turbo Native Modules.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Initialize a Modern JSI-Enabled Project
&lt;/h2&gt;

&lt;p&gt;Unlike our previous playground, we want a framework version where the New Architecture and JSI are turned on by default. We will initialize a project using the latest version.&lt;br&gt;
Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @react-native-community/cli@latest init JsiTurboModuleDemo
&lt;span class="nb"&gt;cd &lt;/span&gt;JsiTurboModuleDemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;h2&gt;
  
  
  Verify New Architecture State
&lt;/h2&gt;

&lt;p&gt;Because we are using the latest version, the JSI engine is active out of the box. Let's verify it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Android: Open android/gradle.properties and verify that newArchEnabled=true is set.&lt;/li&gt;
&lt;li&gt;For iOS: Run cd ios &amp;amp;&amp;amp; bundle exec pod install &amp;amp;&amp;amp; cd ... The CLI automatically configures the Fabric and TurboModule native pods. &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2: Define the JavaScript Spec (Codegen)
&lt;/h2&gt;

&lt;p&gt;The modern architecture relies on strongly typed interfaces to automatically generate the type-safe C++ binding glue code between JavaScript and native files. This tool is called Codegen. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create the Spec Folder Structure
&lt;/h2&gt;

&lt;p&gt;Inside your root directory, create a folder named specs:&lt;/p&gt;

&lt;p&gt;mkdir specs&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create the TypeScript Interface
&lt;/h2&gt;

&lt;p&gt;Inside the specs folder, create a file named NativeCalculatorModule.ts. Paste this precise structural template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TurboModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TurboModuleRegistry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 1. Define the interface contract extending TurboModuleexport &lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Spec&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;TurboModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 👈 Synchronous execution! Returns a number directly instead of using a callback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// 2. Register the module naming convention with the TurboModule provider registry&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;TurboModuleRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getEnforcing&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spec&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NativeCalculatorModule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Dev Note: Look at addNumbers. Notice that it returns a primitive number synchronously. In the legacy JSON bridge, everything had to be an asynchronous callback. JSI completely alters this rule!&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Configure package.json for Codegen
&lt;/h2&gt;

&lt;p&gt;We must tell React Native to scan our new specs folder and generate the matching native code layouts during compilation.&lt;br&gt;
Open your root package.json file and look for the "dependencies" block. Add a new configuration key named "codegenConfig" right at the bottom of the JSON object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"codegenConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AppSpecs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"modules"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsSrcsDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"specs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"android"&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;"javaPackageName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.jsiturbomoduledemo.specs"&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;h2&gt;
  
  
  Step 4: Implement the JSI Module on Android (Kotlin)
&lt;/h2&gt;

&lt;p&gt;With the specification established, let's write our modern addition module using Kotlin.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create the Kotlin Module File
&lt;/h2&gt;

&lt;p&gt;Navigate to android/app/src/main/java/com/jsiturbomoduledemo/ and create a file named CalculatorModule.kt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.jsiturbomoduledemo&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.jsiturbomoduledemo.specs.NativeCalculatorModuleSpec&lt;/span&gt; &lt;span class="c1"&gt;// 👈 Automatically available via Codegen&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nf"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;reactContext:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NativeCalculatorModuleSpec&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Must match the string declared in the TypeScript Spec registry&lt;/span&gt;
    &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NAME&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement the addition method synchronously&lt;/span&gt;
    &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;a:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;b:&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Double&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;companion&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="no"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NativeCalculatorModule"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create the Package Registration File
&lt;/h2&gt;

&lt;p&gt;In the same folder directory, create CalculatorPackage.kt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.jsiturbomoduledemo&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.TurboReactPackage&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.NativeModule&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.bridge.ReactApplicationContext&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.module.model.ReactModuleInfo&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.facebook.react.module.model.ReactModuleInfoProvider&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorPackage&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TurboReactPackage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;reactContext:&lt;/span&gt; &lt;span class="nc"&gt;ReactApplicationContext&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;NativeModule&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kc"&gt;null&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getReactModuleInfoProvider&lt;/span&gt;&lt;span class="o"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;ReactModuleInfoProvider&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ReactModuleInfoProvider&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="n"&gt;moduleInfos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ReactModuleInfo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="n"&gt;moduleInfos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ReactModuleInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// canOverrideExistingModule&lt;/span&gt;
                &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// needsEagerInit&lt;/span&gt;
                &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// isCxxModule&lt;/span&gt;
                &lt;span class="kc"&gt;true&lt;/span&gt;   &lt;span class="c1"&gt;// isTurboModule 👈 Tells the runtime this is a JSI module!&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;moduleInfos&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Update MainApplication.kt
&lt;/h2&gt;

&lt;p&gt;Open android/app/src/main/java/com/jsiturbomoduledemo/MainApplication.kt and register the package inside your getPackages() list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPackages&lt;/span&gt;&lt;span class="o"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ReactPackage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="nc"&gt;PackageList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// Packages that cannot be autolinked yet can be added manually here:&lt;/span&gt;
              &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CalculatorPackage&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 👈 Add this line to register your TurboModule&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Implement the iOS JSI TurboModule (Objective-C++)
&lt;/h2&gt;

&lt;p&gt;On iOS, TurboModule JSI bindings must be implemented in &lt;strong&gt;Objective-C++&lt;/strong&gt; (&lt;code&gt;.mm&lt;/code&gt;) so C++ types can be used for runtime bindings.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create &lt;code&gt;CalculatorModule.h&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;ios/JsiTurboModuleDemo/CalculatorModule.h&lt;/code&gt;:&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="cp"&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
#import &amp;lt;AppSpecs/AppSpecs.h&amp;gt; // Generated by RN Codegen
&lt;/span&gt;
&lt;span class="k"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NSObject&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NativeCalculatorModuleSpec&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create &lt;code&gt;CalculatorModule.mm&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;ios/JsiTurboModuleDemo/CalculatorModule.mm&lt;/code&gt;:&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="cp"&gt;#import "CalculatorModule.h"
#import &amp;lt;React/RCTBridgeModule.h&amp;gt;
&lt;/span&gt;
&lt;span class="k"&gt;@implementation&lt;/span&gt; &lt;span class="nc"&gt;CalculatorModule&lt;/span&gt;

&lt;span class="n"&gt;RCT_EXPORT_MODULE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NativeCalculatorModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSNumber&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;shared_ptr&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;facebook&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TurboModule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;getTurboModule&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;facebook&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ObjCTurboModule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InitParams&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;facebook&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NativeCalculatorModuleSpecJSI&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Ensure files are in the iOS target
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;ios/JsiTurboModuleDemo.xcworkspace&lt;/code&gt; in Xcode and confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CalculatorModule.h&lt;/code&gt; and &lt;code&gt;CalculatorModule.mm&lt;/code&gt; are added to the project.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CalculatorModule.mm&lt;/code&gt; is included in the &lt;strong&gt;JsiTurboModuleDemo&lt;/strong&gt; target’s &lt;strong&gt;Compile Sources&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 6: Consume the synchronous module in JavaScript
&lt;/h2&gt;

&lt;p&gt;Update &lt;code&gt;App.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&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;TextInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NativeCalculatorModule&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./specs/NativeCalculatorModule&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNumber1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNumber2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;25&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleCalculate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Synchronous TurboModule call over JSI&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nativeResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NativeCalculatorModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nativeResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;JSI / TurboModule Calculator&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextInput&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"numeric"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;number1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setNumber1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plus&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextInput&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"numeric"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;number2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setNumber2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Calculate instantly via JSI"&lt;/span&gt; &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleCalculate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resultText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Instant Result: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&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="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginBottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderWidth&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="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginVertical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginVertical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;resultText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Build and run
&lt;/h2&gt;

&lt;p&gt;From project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iOS (run once after native/codegen changes)&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
npx react-native run-ios

&lt;span class="c"&gt;# Android&lt;/span&gt;
npx react-native run-android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If iOS build still uses stale artifacts, clean build folder in Xcode and rerun.&lt;/p&gt;




&lt;h2&gt;
  
  
  📂 Get the Full JSI Source Code
&lt;/h2&gt;

&lt;p&gt;Want to skip the file configurations and explore a fully functional, zero-latency production setup right now? I have published the entire sandbox codebase—featuring the TypeScript spec files, Kotlin (Android) configurations, and Objective-C++ (iOS) native interfaces—to GitHub.&lt;/p&gt;

&lt;p&gt;Feel free to clone it, reference the layout files, and use it as your modern, New Architecture practice template!&lt;br&gt;
👉 View the Complete JSI / TurboModule Sandbox on GitHub&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start with the Repo:
&lt;/h2&gt;

&lt;h1&gt;
  
  
  Clone the repository
&lt;/h1&gt;

&lt;p&gt;git clone &lt;a href="https://github.com" rel="noopener noreferrer"&gt;https://github.com&lt;/a&gt;&lt;br&gt;
cd react-native-jsi-turbo-module-demo&lt;/p&gt;

&lt;h1&gt;
  
  
  Install project dependencies
&lt;/h1&gt;

&lt;p&gt;npm install&lt;/p&gt;

&lt;h1&gt;
  
  
  Run on Android (New Architecture active by default)
&lt;/h1&gt;

&lt;p&gt;npx react-native run-android&lt;/p&gt;

&lt;h1&gt;
  
  
  Run on iOS (Installs Fabric and TurboModule pods dynamically)
&lt;/h1&gt;

&lt;p&gt;cd ios &amp;amp;&amp;amp; bundle exec pod install &amp;amp;&amp;amp; cd ..&lt;br&gt;
npx react-native run-ios&lt;/p&gt;







&lt;h2&gt;
  
  
  ⚖️ Summary: Legacy JSON Bridge vs. Modern JSI
&lt;/h2&gt;

&lt;p&gt;To wrap up this evolution timeline, let's look at a direct architectural comparison between what we built in the first playground versus our modern JSI sandbox:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Architectural Feature&lt;/th&gt;
&lt;th&gt;Legacy JSON Bridge (Pre-0.76)&lt;/th&gt;
&lt;th&gt;Modern JSI / TurboModules (0.76+)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Communication Type&lt;/td&gt;
&lt;td&gt;Asynchronous Only (Batched message queues)&lt;/td&gt;
&lt;td&gt;Synchronous &amp;amp; Asynchronous (Direct method execution)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Overhead&lt;/td&gt;
&lt;td&gt;High (JSON stringification and parsing delays)&lt;/td&gt;
&lt;td&gt;Zero (Direct sharing of C++ memory reference points)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type Safety&lt;/td&gt;
&lt;td&gt;None (Loose arguments verified manually at runtime)&lt;/td&gt;
&lt;td&gt;Guaranteed (Enforced at compile-time via Codegen Specs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native Files (iOS)&lt;/td&gt;
&lt;td&gt;Standard Objective-C (.m)&lt;/td&gt;
&lt;td&gt;Objective-C++ (.mm) required for C++ integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native Files (Android)&lt;/td&gt;
&lt;td&gt;Java (.java)&lt;/td&gt;
&lt;td&gt;Modern Kotlin (.kt) natively integrated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI Updates&lt;/td&gt;
&lt;td&gt;Prone to lag / frame drops on heavy calculations&lt;/td&gt;
&lt;td&gt;Fluid, zero-latency execution directly on the UI thread&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Understanding where React Native came from helps you appreciate where it is today. While the legacy JSON bridge was a groundbreaking concept that powered cross-platform apps for nearly a decade, the shift to JSI turns React Native into a truly native-speed engine.&lt;br&gt;
As a mobile developer, mastering both sides of this equation prepares you to support aging enterprise apps while confidently architecting high-performance modern applications.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>subrata</category>
      <category>tutorial</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
