<?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: Mauricio Reatto Duarte</title>
    <description>The latest articles on DEV Community by Mauricio Reatto Duarte (@mauriciord).</description>
    <link>https://dev.to/mauriciord</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F143072%2F1647833a-2186-4cf3-a682-88f449321584.jpg</url>
      <title>DEV Community: Mauricio Reatto Duarte</title>
      <link>https://dev.to/mauriciord</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mauriciord"/>
    <language>en</language>
    <item>
      <title>xState: My Practical Experience and Insights</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Fri, 30 May 2025 20:34:53 +0000</pubDate>
      <link>https://dev.to/mauriciord/xstate-my-practical-experience-and-insights-4d4d</link>
      <guid>https://dev.to/mauriciord/xstate-my-practical-experience-and-insights-4d4d</guid>
      <description>&lt;p&gt;After spending considerable time working with XState in production environments, I want to share my honest perspective on this state management library. While XState brings powerful concepts from computer science to JavaScript applications, my experience has revealed both impressive capabilities and significant challenges that teams should consider.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good: Visual Development Done Right
&lt;/h2&gt;

&lt;p&gt;Let's start with what XState absolutely nails: the diagram tool. Being able to create no-code diagrams that represent your entire workflow is genuinely impressive. You can visually design your state machines and then generate TypeScript or React code directly from these diagrams. This visual-first approach helps bridge the gap between technical and non-technical team members during planning sessions.&lt;/p&gt;

&lt;p&gt;The debugging experience is another highlight. You can attach a running machine to an inspector that opens your diagram in real-time in a separate window. Watching your application flow through states visually while debugging is incredibly powerful you can see exactly what's happening and where within your state machine as your application runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Not-So-Good: When Power Comes at a Cost
&lt;/h2&gt;

&lt;p&gt;However, there's a catch with the diagram tool: many useful features are locked behind a paywall. While the free tier is functional, you'll likely hit limitations quickly in any serious project.&lt;/p&gt;

&lt;p&gt;But the real challenges go deeper than pricing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Complexity Trap
&lt;/h3&gt;

&lt;p&gt;XState can quickly become overkill for simple state transitions. What might be a few lines of code with useState or useReducer can balloon into a complex state machine configuration. The learning curve is steep really steep. Coming from React Context or Redux, you'll struggle with fundamental concepts. What exactly is a "state" versus "context" in XState? The mental model is fundamentally different, and it takes significant time to internalize.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too Many Ways to Solve the Same Problem
&lt;/h3&gt;

&lt;p&gt;XState is deliberately unopinionated, which sounds great in theory but becomes problematic at scale. You can implement the same functionality in numerous ways, and without extremely well-documented team standards, your codebase can quickly become inconsistent and hard to maintain.&lt;/p&gt;

&lt;p&gt;Yes, you could argue this is a documentation or process problem rather than an XState problem. But when a tool makes it this easy to create inconsistency, that's a valid criticism of the tool itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript: A Second-Class Citizen?
&lt;/h3&gt;

&lt;p&gt;For a library that targets complex applications, XState's TypeScript support is surprisingly weak. Type inference often falls short, especially when you try to maintain good architectural practices. Want to extract action creators into separate files for unit testing? Prepare for TypeScript gymnastics and compromises.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Elephant in the Room
&lt;/h2&gt;

&lt;p&gt;It's 2025, so we need to address the AI coding assistant situation. You might think, "Well, AI tools should make working with XState easier!" Unfortunately, that's not the case:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation Limbo&lt;/strong&gt; : XState v5's official documentation remains incomplete. How can AI assistants help when even the official sources are lacking?&lt;/p&gt;&lt;/li&gt;
&lt;li&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%2Fxlga922eswjywxkfjkwz.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%2Fxlga922eswjywxkfjkwz.png" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version Confusion&lt;/strong&gt; : The breaking changes from v4 to v5, combined with limited v5 adoption, mean AI suggestions often mix syntaxes or suggest outdated patterns. Most training data is still v4-heavy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Garbage In, Garbage Out&lt;/strong&gt; : If developers are struggling with XState's complexity and creating suboptimal implementations (as discussed above), then AI models trained on this code will perpetuate these problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Visual Complexity with Sub-machines
&lt;/h3&gt;

&lt;p&gt;One last pain point: sub-machines (machines nested within parent machines) are poorly represented in the visual diagrams. What should be a clear hierarchical view often becomes a confusing mess, defeating the purpose of visual state management.&lt;/p&gt;

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

&lt;p&gt;XState is undoubtedly powerful and brings valuable computer science concepts to JavaScript. The visual tooling and debugging capabilities are genuinely innovative. However, the steep learning curve, lack of opinionation, weak TypeScript support, and limited AI assistance make it a challenging choice for many teams.&lt;/p&gt;

&lt;p&gt;Before adopting XState, ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Do you really need this level of state machine complexity?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does your team have the time and patience for the learning curve?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can you establish and maintain strict coding standards?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you prepared to work without strong AI assistance?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For complex, long-lived applications with dedicated teams, XState might be worth the investment. For everyone else, simpler state management solutions might serve you better.&lt;/p&gt;

&lt;p&gt;What's your experience with XState? Have you found ways to mitigate these challenges? I'd love to hear your thoughts in the comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ref
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stately.ai/docs" rel="noopener noreferrer"&gt;Stately + XState docs | Stately&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stately.ai/registry/projects" rel="noopener noreferrer"&gt;Diagram Tool | Stately&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stately.ai/registry/projects" rel="noopener noreferrer"&gt;What is state and&lt;/a&gt; &lt;a href="https://stately.ai/docs" rel="noopener noreferrer"&gt;state man&lt;/a&gt;&lt;a href="https://app.studyraid.com/en/read/11437/358330/what-is-state-and-state-management" rel="noopener noreferrer"&gt;agement - Mastering XState: A Comprehensive Guide to Actor-Based State Management | StudyRaid&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;]]&amp;gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fixing "Can't resolve module 'next/headers'" for Next 12 + Next Auth</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Mon, 18 Sep 2023 21:08:29 +0000</pubDate>
      <link>https://dev.to/mauriciord/fixing-cant-resolve-module-nextheaders-for-next-12-next-auth-g6k</link>
      <guid>https://dev.to/mauriciord/fixing-cant-resolve-module-nextheaders-for-next-12-next-auth-g6k</guid>
      <description>&lt;p&gt;If you use NextAuth within your Next.js v12.x project, you've probably faced this issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can't resolve module 'next/headers'

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

&lt;/div&gt;



&lt;p&gt;The only way I found it was by applying a &lt;code&gt;patch-package&lt;/code&gt; to the Next Auth package. Let's fix it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change your &lt;strong&gt;package.json&lt;/strong&gt; :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// package.json
"scripts": {
    "postinstall": "patch-package"
}

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

&lt;/div&gt;



&lt;p&gt;Then execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D patch-package postinstall-postinstall

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

&lt;/div&gt;



&lt;p&gt;After that change, you'll need to change two files inside your &lt;code&gt;node_modules&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;node_modules/next-auth/next/index.js&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;node_modules/next-auth/src/next/index.ts&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modify them one by one:&lt;/p&gt;

&lt;p&gt;you need to look for "next/headers" and you'll notice two pieces using it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// node_modules/next-auth/next/index.js
// node_modules/next-auth/src/next/index.ts

if (isRSC) {
     options = Object.assign({}, args[0], {
      providers: []
     });

    const {
    headers,
    cookies
    } = require("next/headers");

    req = {
      headers: Object.fromEntries(headers()),
      cookies: Object.fromEntries(cookies().getAll().map(c =&amp;gt; [c.name, c.value]))
    };
    res = {
      getHeader() {},
      setCookie() {},
      setHeader() {}
    };
} else {
    req = args[0];
    res = args[1];
    options = Object.assign({}, args[2], {
        providers: []
    });
}

/*
* replace with else only
*/
    req = args[0];
    res = args[1];
    options = Object.assign({}, args[2], {
        providers: []
    });


// node_modules/next-auth/next/index.js
// node_modules/next-auth/src/next/index.ts

// remove this const { headers, cookies } = require("next/headers")
// from async function NextAuthRouteHandler(

cookies: Object.fromEntries(
    Array.from(req.cookies.entries())
        .map(([name, value]) =&amp;gt; [name, value])
),
headers: req.headers, // you don't need this as Headers

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

&lt;/div&gt;



&lt;p&gt;After applying those changes, you must run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn patch-package next-auth

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

&lt;/div&gt;



&lt;p&gt;This will create the patch file. You can also refer to this &lt;a href="https://gist.github.com/mauriciord/9af1ebd21aa066c9dd73860a90996efa" rel="noopener noreferrer"&gt;gist here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's it. Byte bye!&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.: Troubleshooting
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm -rf node_modules yarn.lock package-lock.json .next

yarn

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

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>[WIP] Rust - NOTES</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Mon, 11 Sep 2023 23:19:24 +0000</pubDate>
      <link>https://dev.to/mauriciord/wip-rust-notes-4e76</link>
      <guid>https://dev.to/mauriciord/wip-rust-notes-4e76</guid>
      <description>&lt;h3&gt;
  
  
  Tuple
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let numbers: (i32, i32, f64) = (1, 2, 3.5);

// destructuring
let (a, b, c) = numbers;

// mutable
let mut mau = (10, 11, 12)
mau.0 = 90 // (90, 11, 12)

mau = (90, 91, 92) // pattern matching

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;need to respect the type to avoid &lt;code&gt;mismatched types&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Array
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let neo: [i32;3] = [1, 2, 3]
neo[1] // 2

let mut morpheu = [1.1, 2.2, 3.3]
morpheu[2] = 10.15

// slice
&amp;amp;neo[1..] // [2, 3]
&amp;amp;neo[..2] // [1, 2]
&amp;amp;neo[1..2] // [2]

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;arrays should have only one type&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Out-of-bound error
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Trying to get an element out of the limits: &lt;strong&gt;index out of bounds&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memory Awareness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;STATIC memory needs fixed-size
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static _Y: u32 = 13

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;STACK are local variables,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static _Y: u32 = 13

fn main() {
    let x = 5;
    let z = true;
    let numbers = [1, 2, 3];
}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;HEAP memory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static _Y: u32 = 13

fn main() {
    let x = 5;
    let z = true;
    let numbers = [1, 2, 3];

    let users = get_users();
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Memory Cleanup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;drop&lt;/strong&gt; method to clean up it&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>What I want for 2023</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Tue, 17 Jan 2023 00:08:54 +0000</pubDate>
      <link>https://dev.to/mauriciord/what-i-want-for-2023-4m0k</link>
      <guid>https://dev.to/mauriciord/what-i-want-for-2023-4m0k</guid>
      <description>&lt;p&gt;2023 has already started and a small TODO list (at least, giving them a try) for this year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Be an expert with &lt;a href="https://www.algolia.com/" rel="noopener noreferrer"&gt;Algolia&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://trpc.io/" rel="noopener noreferrer"&gt;tRPC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.solidjs.com/" rel="noopener noreferrer"&gt;SolidJS&lt;/a&gt; (They've started building the SolidStart and I want to give it a try)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  books
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/Engineering-Management-Rest-Sarah-Drasner-ebook/dp/B0BGYVDX35" rel="noopener noreferrer"&gt;Engineering Management for the Rest of Us 1, Drasner, Sarah, eBook -&lt;/a&gt; &lt;a href="http://Amazon.com" rel="noopener noreferrer"&gt;Amazon.com&lt;/a&gt; (I've already been reading this)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/Staff-Engineers-Path-Tanya-Reilly-ebook/dp/B0BG16Y553/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;qid=&amp;amp;sr=" rel="noopener noreferrer"&gt;The Staff Engineer's Path 1, Reilly, Tanya, eBook -&lt;/a&gt; &lt;a href="http://Amazon.com" rel="noopener noreferrer"&gt;Amazon.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/Software-Architecture-Parts-Neal-Ford-ebook/dp/B09H2H5QKC" rel="noopener noreferrer"&gt;Software Architecture: The Hard Parts 1, Ford, Neal, Richards, Mark, Sadalage, Pramod, Dehghani, Zhamak, eBook -&lt;/a&gt; &lt;a href="http://Amazon.com" rel="noopener noreferrer"&gt;Amazon.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/Effective-Software-Testing-developers-guide-ebook/dp/B09WBNJYLX" rel="noopener noreferrer"&gt;Effective Software Testing: A developer's guide , Aniche, Maurizio, eBook -&lt;/a&gt; &lt;a href="http://Amazon.com" rel="noopener noreferrer"&gt;Amazon.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  talks
&lt;/h3&gt;

&lt;p&gt;I wish to give some talks about software development (at least two talks)&lt;/p&gt;

&lt;p&gt;I've returned with my blog posts, so I hope I'll have had a lot of posts by the end of this year.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JS - The Event Loop</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Thu, 05 Jan 2023 22:20:44 +0000</pubDate>
      <link>https://dev.to/mauriciord/js-the-event-loop-3ep3</link>
      <guid>https://dev.to/mauriciord/js-the-event-loop-3ep3</guid>
      <description>&lt;p&gt;It's been a long time without posting anything here, but I'm back.&lt;br&gt;&lt;br&gt;
Let's talk about Javascript's Event Loop. As you may know, JS is a &lt;strong&gt;&lt;em&gt;Single-Threaded&lt;/em&gt;&lt;/strong&gt; language, so it can only execute 1 task simultaneously.&lt;br&gt;&lt;br&gt;
Assuming we have the &lt;em&gt;Javascript Engine&lt;/em&gt;, a program built to execute Javascript code, we need to consider that each browser has a &lt;em&gt;Javascript Engine:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chrome&lt;/strong&gt; and many other Chromium browsers have the V8 Engine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Safari&lt;/strong&gt; has the JavascriptCore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Firefox&lt;/strong&gt; has the SpiderMonkey&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These engines can be different in implementation across browsers, but at least they contain two parts:&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%2F10jw4wdtges7ena2un4k.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%2F10jw4wdtges7ena2un4k.png" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory Heap:&lt;/strong&gt; A data store with memory allocation to store objects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Call Stack:&lt;/strong&gt; It's a stack that keeps track of running functions. Every time the code is calling a function, it pushes that piece of code (&lt;em&gt;stack frame&lt;/em&gt;) onto the stack. The &lt;em&gt;stack frame&lt;/em&gt; will contain information about the functions and their local variables.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;When a function is called, it goes onto the top of the call stack, and when that same function ends, it's popped out the call stack. &lt;strong&gt;LIFO&lt;/strong&gt; (last-in-first-out) is the name given to this principle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OK, now you've got the basics of the Call Stack. But, what would happen in the case of incrementing a &lt;code&gt;setTimeout(foo, 2000)&lt;/code&gt; in the code?&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Runtime Environment
&lt;/h2&gt;

&lt;p&gt;The JS Engine runs our code in this larger environment known as &lt;em&gt;JavaScript Runtime Environment.&lt;/em&gt; It provides some &lt;strong&gt;web APIs&lt;/strong&gt; to be able to access the browser's functions like DOM manipulation, timers, HTTP Requests, and so on.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But, what would happen in the case of incrementing a &lt;code&gt;setTimeout(foo, 2000)&lt;/code&gt; in the code?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpeo6i31nvnj0v8ah24s8.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%2Fpeo6i31nvnj0v8ah24s8.png" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Task Queue
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Web APIs&lt;/strong&gt; move callbacks into the &lt;strong&gt;Task Queue&lt;/strong&gt; , to wait for the &lt;strong&gt;Call Stack&lt;/strong&gt; to be empty, and start executing that callback function. Then, the &lt;strong&gt;Task Queue&lt;/strong&gt; is a data structure responsible for storing asynchronous callbacks to be moved to the &lt;strong&gt;Call Stack&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
&lt;em&gt;On the example above, you can notice that after the delay of 2000ms, the foo() function has been moved to the Task Queue, waiting to be executed when the Call Stack becomes empty.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This queue is also known as the "Macrotask Queue", "Callback Queue", or "Message Queue".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This overall process is known as &lt;strong&gt;Event Loop&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Remove one task from the &lt;strong&gt;Task Queue&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Executing code until the &lt;strong&gt;Call Stack&lt;/strong&gt; is empty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rendering any changes to the DOM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Going to &lt;em&gt;step 1&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fb0j6156ex7x8y2u0bs0v.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%2Fb0j6156ex7x8y2u0bs0v.png" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/embed/pedantic-tdd-upyc0q?expanddevtools=1&amp;amp;fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark&amp;amp;view=preview" rel="noopener noreferrer"&gt;https://codesandbox.io/embed/pedantic-tdd-upyc0q?expanddevtools=1&amp;amp;fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark&amp;amp;view=preview&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Promises?
&lt;/h2&gt;

&lt;p&gt;After Promises have been introduced to the language, there's a new Queue in the picture, and that one is the &lt;strong&gt;Microtask Queue&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microtask Queue
&lt;/h2&gt;

&lt;p&gt;Known as well as &lt;em&gt;Job Queue&lt;/em&gt;, the &lt;strong&gt;Microtask Queue&lt;/strong&gt; is responsible for holding the callback function of Promises.&lt;br&gt;&lt;br&gt;
The known callback functions of Promises are &lt;code&gt;.then()&lt;/code&gt;, &lt;code&gt;.catch()&lt;/code&gt;, &lt;code&gt;.finally()&lt;/code&gt;, and &lt;code&gt;async/await&lt;/code&gt; .&lt;br&gt;&lt;br&gt;
They can be manually queued using the &lt;code&gt;queueMicrotask()&lt;/code&gt; function.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Microtasks have more priority compared to Macro tasks&lt;/strong&gt; because the entire microtask queue should be empty before Browser checks the Task Queue.&lt;/p&gt;

&lt;p&gt;Then, with those new concepts in mind, we need to update our &lt;strong&gt;Event Loop&lt;/strong&gt; workflow:&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%2F6ibc7v3tg7vzjfaqq6zb.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%2F6ibc7v3tg7vzjfaqq6zb.png" width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Removing one task from the &lt;strong&gt;Task Queue&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Executing code until the &lt;strong&gt;Call Stack&lt;/strong&gt; is empty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running all microtasks until the microtask queue is empty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rendering any changes to the DOM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Going to &lt;em&gt;step 1&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For all of these steps, we have a name to point to all of them, and we call as &lt;strong&gt;Concurrency Model&lt;/strong&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1672956249099%2Fa17a0b5c-88ff-4912-972d-e378f2ce3b97.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1672956249099%2Fa17a0b5c-88ff-4912-972d-e378f2ce3b97.png" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Big computations and slow functions can make the entire page unresponsive. When you fall into situations like these, you can try solutions like &lt;strong&gt;chunking&lt;/strong&gt; , or even web workers.&lt;br&gt;&lt;br&gt;
The main idea behind chunking is to split big functions into smaller functions. You can achieve that using &lt;code&gt;setTimeout&lt;/code&gt; for some iterations, forcing them to be chunked, and moving them to the end of the &lt;strong&gt;Task Queue&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I've got a friend that was used to saying: &lt;em&gt;"There's nothing a setTimeout() can't fix"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I hope you've enjoyed this text. Please, press &lt;strong&gt;like&lt;/strong&gt; and don't forget to share it with your colleagues or friends. See you!&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html" rel="noopener noreferrer"&gt;What the heck is the event loop anyway? Philip Roberts (&lt;/a&gt;&lt;a href="http://jsconf.eu" rel="noopener noreferrer"&gt;jsconf.eu&lt;/a&gt;&lt;a href="https://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html" rel="noopener noreferrer"&gt;)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop" rel="noopener noreferrer"&gt;The event loop - JavaScript | MDN (&lt;/a&gt;&lt;a href="http://mozilla.org" rel="noopener noreferrer"&gt;mozilla.org&lt;/a&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop" rel="noopener noreferrer"&gt;)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Web Development Fundamentals - Clients &amp; Servers</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Fri, 25 Mar 2022 01:04:50 +0000</pubDate>
      <link>https://dev.to/mauriciord/web-development-fundamentals-clients-servers-4mdh</link>
      <guid>https://dev.to/mauriciord/web-development-fundamentals-clients-servers-4mdh</guid>
      <description>&lt;h2&gt;
  
  
  Client
&lt;/h2&gt;

&lt;p&gt;A client is a process that basically requests data from a server. As we're talking about the web, the browsers are clients requesting HTML pages from servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server
&lt;/h2&gt;

&lt;p&gt;Process providing service/data for a client&lt;/p&gt;

&lt;h2&gt;
  
  
  Client/Server Model
&lt;/h2&gt;

&lt;p&gt;Clients requesting data from servers&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: A piece of code/machine/software can be both server and client at the same time because it could act as a client requesting data from a database and serving a service as a server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've been used to associate Clients to Frontend and Servers to Backend&lt;/p&gt;

&lt;p&gt;About the codebase executing on the client and the server:&lt;/p&gt;

&lt;h3&gt;
  
  
  Client
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;End-users can see all of the code (Browsers)&lt;/li&gt;
&lt;li&gt;Need to be fast&lt;/li&gt;
&lt;li&gt;Low computing power (depends on the end-user)&lt;/li&gt;
&lt;li&gt;Cannot access Database directly (you can store information in the Browser, but in this case, we need information/data shared across users)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hidden code and implementation details&lt;/li&gt;
&lt;li&gt;Slow (compared to clients because we need to wait on the network)&lt;/li&gt;
&lt;li&gt;Scalable computing power (💰💰💰💰💰)&lt;/li&gt;
&lt;li&gt;Can access Database easily and share information across users&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Refactoring culture</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Sun, 12 Jul 2020 21:38:23 +0000</pubDate>
      <link>https://dev.to/mauriciord/refactoring-culture-1o1a</link>
      <guid>https://dev.to/mauriciord/refactoring-culture-1o1a</guid>
      <description>&lt;p&gt;When you're doing a big refactoring into your project, there's sometimes that is better to create new things than modify the existing things. It's a good plan, because you make sure that you don't break anything.&lt;/p&gt;

&lt;p&gt;It was a great tip from &lt;a class="mentioned-user" href="https://dev.to/sibelius"&gt;@sibelius&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm on a refactoring for update to latest stable Material-UI, changing forms from Redux Form to Formik and creating new layout to these forms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even with a complete copy of a file, just changing its name and a single line, it's easier to make incremental changes to the files that'll use your new refactored component&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>developer</category>
    </item>
    <item>
      <title>Production Ready GraphQL Summary — Part I</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Thu, 23 Apr 2020 13:26:18 +0000</pubDate>
      <link>https://dev.to/mauriciord/production-ready-graphql-summary-part-i-1o3c</link>
      <guid>https://dev.to/mauriciord/production-ready-graphql-summary-part-i-1o3c</guid>
      <description>&lt;p&gt;I'm reading this &lt;a href="https://book.productionreadygraphql.com/" rel="noopener noreferrer"&gt;book with GraphQL content&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks &lt;a class="mentioned-user" href="https://dev.to/leonardomso"&gt;@leonardomso&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%2Fi%2F1mouv60pagi9ih5vuojp.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%2Fi%2F1mouv60pagi9ih5vuojp.png" alt="book" width="800" height="1075"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pagination: Cursor Pagination
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cursor pagination is generally a great choice, because of the accuracy and performance&lt;/li&gt;
&lt;li&gt;Maybe it's the most common pattern in GraphQL at the moment&lt;/li&gt;
&lt;li&gt;This pattern lets us design more complex use cases, because of Connection and Edge types&lt;/li&gt;
&lt;li&gt;Relay clients integrate perfectly with your API because of that&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Global Identification: Global ID — Node
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Like Connections, they can be a good pattern even outside of a Relay context&lt;/li&gt;
&lt;li&gt;Opaque IDs are recommended&lt;/li&gt;
&lt;li&gt;You necessarily don't need global identification if you're not planning to use Relay&lt;/li&gt;
&lt;li&gt;Ensure your global identification contains enough context to globally route to a node, especially in a distributed architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Non-Nullability
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It lets clients avoid defensive code/conditionals&lt;/li&gt;
&lt;li&gt;It helps to build more predictable schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;tradeoffs/warnings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's very hard to predict what can be null&lt;/li&gt;
&lt;li&gt;Non-null fields and arguments are harder to evolve. Going from non-null to null is a breaking change, but the opposite is not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;guidelines for nullability:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should almost always nullable fields that return object types that are backed by database associations, network calls, or anything that could potentially fail&lt;/li&gt;
&lt;li&gt;Non-null for arguments, because it's more predictable and easy to understand API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it.&lt;br&gt;
My first part of the book summary. Thank you.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>summary</category>
      <category>relay</category>
      <category>bookreview</category>
    </item>
    <item>
      <title>How to insert an Expo project in a Monorepo</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Thu, 09 Apr 2020 01:10:29 +0000</pubDate>
      <link>https://dev.to/expolovers/how-to-insert-an-expo-project-in-a-monorepo-5ab0</link>
      <guid>https://dev.to/expolovers/how-to-insert-an-expo-project-in-a-monorepo-5ab0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this post, I'll cover about adding an Expo project inside a Monorepo project. I found on the internet so many people trying to do this, asking in some forums, or commenting something like "+1" at the Github issues. So, the purpose of this post is not to teach how to create a monorepo, is how to insert your Expo application inside a Monorepo.&lt;/p&gt;

&lt;p&gt;Of course, you could help me by liking "+1" in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monorepo
&lt;/h2&gt;

&lt;p&gt;I won't go deep in Monorepo's explanation, but basically, is an architectural concept. Instead of a lot of individual repositories, you keep all your isolated code parts inside one repository. It's very different from the monolithic repo.&lt;/p&gt;

&lt;p&gt;Good examples and inspirations with Monorepo are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/expo/expo" rel="noopener noreferrer"&gt;The Expo itself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/FotonTech/golden-stack" rel="noopener noreferrer"&gt;Golden Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/entria/entria-fullstack" rel="noopener noreferrer"&gt;Entria Fullstack Monorepo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you understand the main monorepo structure, you start to see a lot of famous libraries that you or your team use that is Monorepo.&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%2F9hiutepysm7duucknis3.gif" 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%2F9hiutepysm7duucknis3.gif" alt="https://media.giphy.com/media/lJ0JGfNBrRWJVCRChd/giphy.gif" width="470" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get to work
&lt;/h2&gt;

&lt;p&gt;First of all, you must create an Expo project (of course, if you haven't already created one) in some folder. To do this is simple like:&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;# Install the command line tools&lt;/span&gt;
    &lt;span class="c"&gt;# npm install --global expo-cli or&lt;/span&gt;
    &lt;span class="c"&gt;# yarn global add expo-cli&lt;/span&gt;

    &lt;span class="c"&gt;# ~/workspace&lt;/span&gt;

    &lt;span class="c"&gt;# Create a new project&lt;/span&gt;
    expo init my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;More info: &lt;a href="https://docs.expo.io/versions/v37.0.0/" rel="noopener noreferrer"&gt;https://docs.expo.io/versions/v37.0.0/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can overwrite &lt;code&gt;my-project&lt;/code&gt; with your the name of your choice (mine is &lt;code&gt;expo-app&lt;/code&gt;), then select &lt;strong&gt;Blank Template (Managed)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, move this Expo project folder inside the Monorepo folder:&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;# ~/workspace&lt;/span&gt;
    &lt;span class="nb"&gt;mv &lt;/span&gt;expo-app monorepo/packages/expo-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the Expo project is inside the Monorepo. But, we need to adjust some things to be able to run Expo inside this Monorepo.&lt;/p&gt;

&lt;p&gt;We need to set the package name at Expo project &lt;code&gt;package.json&lt;/code&gt; :&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~/workspace/monorepo/packages/expo-app/package.json&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;"@monorepo/expo-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"__generated__/AppEntry.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&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 &lt;code&gt;"main"&lt;/code&gt; key is a special configuration from Expo, so we really need to set that.&lt;/p&gt;

&lt;p&gt;After that, let's add two essential libraries to make our Expo project work. At the monorepo root folder, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    yarn workspace @monorepo/expo-app add expo-yarn-workspaces metro-config &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="nt"&gt;-W&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Flags:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-W&lt;/code&gt;: Adds the libraries on the root&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-D&lt;/code&gt;: The same as &lt;code&gt;—-dev&lt;/code&gt; to add as devDependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Metro config
&lt;/h3&gt;

&lt;p&gt;Let's configure our Metro, so create a file &lt;strong&gt;metro.config.js&lt;/strong&gt; at &lt;code&gt;monorepo/packages/expo-app&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// ~/workspace/monorepo/packages/expo-app/metro.config.js&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;createMetroConfiguration&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expo-yarn-workspaces&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createMetroConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we need to set insert some scripts at &lt;code&gt;package.json&lt;/code&gt; again:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~/workspace/monorepo/packages/expo-app/package.json&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;"@monorepo/expo-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"__generated__/AppEntry.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"postinstall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo-yarn-workspaces postinstall"&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;
  
  
  Extra configuration :: Typescript
&lt;/h3&gt;

&lt;p&gt;If you don't want to add Typescript, you can skip this section.&lt;/p&gt;

&lt;p&gt;Probably your monorepo root folder should contain a &lt;code&gt;tsconfig.json&lt;/code&gt;, so let's add one to the Expo App package and extend the configuration on the root.&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~/workspace/monorepo/packages/expo-app/tsconfig.json&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;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../../tsconfig.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&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;"allowSyntheticDefaultImports"&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;"esModuleInterop"&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;"experimentalDecorators"&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;"forceConsistentCasingInFileNames"&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;"importHelpers"&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;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-native"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"lib"&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;"dom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"noFallthroughCasesInSwitch"&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;"noEmit"&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;"noEmitHelpers"&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;"noImplicitReturns"&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;"noUnusedLocals"&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;"noUnusedParameters"&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;"skipLibCheck"&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;"strict"&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;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&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;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;autocomplete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;paths&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"paths"&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;"*"&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;"src/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assets/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"assets/*"&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;"assets/*"&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;"removeComments"&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;"typeRoots"&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;"node_modules/@types"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src/@types"&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;"include"&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;"src"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&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="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./node_modules"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./node_modules/*"&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;You don't need to use &lt;code&gt;"extends"&lt;/code&gt; key if your monorepeo doesn't contain a TS config yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last step
&lt;/h2&gt;

&lt;p&gt;To start building your product, you should clean/reset your monorepo project, because of the &lt;code&gt;"postinstall"&lt;/code&gt; script inside the expo app package.&lt;/p&gt;

&lt;p&gt;You can remove all &lt;code&gt;node_modules&lt;/code&gt; or something like &lt;code&gt;yarn --force&lt;/code&gt; on the root folder.&lt;/p&gt;

&lt;p&gt;After that, you should run &lt;code&gt;yarn install&lt;/code&gt; again, and you'll be able to develop &amp;amp; build your great product using Expo universal Apps :-]&lt;/p&gt;

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

&lt;p&gt;You can look at my &lt;a href="https://github.com/FotonTech/golden-stack/pull/30" rel="noopener noreferrer"&gt;merged PR inserting an Expo Managed Workflow inside a Monorepo here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whats next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expo - Bare Workflow inside a Monorepo&lt;/li&gt;
&lt;li&gt;Relay Client to use GraphQL&lt;/li&gt;
&lt;li&gt;Or you can comment something to do with Expo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you. \o/&lt;/p&gt;

</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>react</category>
      <category>monorepo</category>
    </item>
    <item>
      <title>A PWA Expo Web using CRA - From ZERO to Deploy</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Wed, 11 Mar 2020 19:42:37 +0000</pubDate>
      <link>https://dev.to/expolovers/a-pwa-expo-web-using-cra-from-zero-to-deploy-acm</link>
      <guid>https://dev.to/expolovers/a-pwa-expo-web-using-cra-from-zero-to-deploy-acm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this post, basically, I will init a Create React App using CRA CLI and inject the Expo SDK Tools to generate a PWA, and with the same codebase, have an iOS and Android App.&lt;/p&gt;

&lt;p&gt;To begin, lets annotate the main tools that we'll use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create React App Boilerplate&lt;/li&gt;
&lt;li&gt;Expo SDK&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expo HTML Elements&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;React Native Web&lt;/li&gt;
&lt;li&gt;Styled Components&lt;/li&gt;
&lt;li&gt;Netlfy/Now Deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using the CRA Boilerplate
&lt;/h2&gt;

&lt;p&gt;To get our first boilerplate, lets try this command:&lt;/p&gt;

&lt;p&gt;You will get the full React Application provided by Facebook Team&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npx create-react-app pwaExpoTutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding React Native Ecosystem
&lt;/h2&gt;

&lt;p&gt;For adding a React Native ecosystem we should add some libraries:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add expo react-native react-native-web @expo/html-elements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After that, we can remove some irrelevant files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;public&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.css&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.test&lt;/code&gt; files (you can add your own test tool after)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding secondary libraries
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expo install react-native-svg
yarn add react-native-web-hooks react-native-animatable styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;React Native SVG:&lt;/strong&gt; SVG Support (Installed with Expo, because it uses Yarn and install the appropriate version to the Expo SDK)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Native Web Hooks:&lt;/strong&gt; React Hooks to be used in Web platform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Native Animatable:&lt;/strong&gt; A library to add animation to our SVG, simulating the initial CRA boilerplate&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Babel configuration
&lt;/h2&gt;

&lt;p&gt;It's good to configure Babel in our project, so install the expo preset and insert a &lt;strong&gt;babel.config.js&lt;/strong&gt; on project root folder&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D babel-preset-expo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;babel.config.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;presets&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;expo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating shared styled components
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;strong&gt;componentsWithStyles&lt;/strong&gt; inside something like &lt;code&gt;src/shared&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&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;styled-components/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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Animatable&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-animatable&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;Header&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Paragraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Anchor&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;@expo/html-elements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&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="nf"&gt;attrs&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="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Animatable&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="s2"&gt;`
      flex: 1;
      align-items: center;
      justify-content: center;
      text-align: center;
      width: 100%;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
      background-color: #282c34;
      flex: 1;
      justify-content: center;
      align-items: center;
      width: 100%;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Paragraph&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
      color: white;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Anchor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
      color: #61dafb;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Animatable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&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="na"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rotate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;iterationCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;infinite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;easing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;aspectRatio&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="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;`
      width: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px;
      height: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thinking in our logo (the SVG provided on initial CRA boilerplate), we need to set an aspect ratio to it, so create a file called &lt;strong&gt;AspectView.js&lt;/strong&gt; inside some folder, I put it inside &lt;code&gt;src/components&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;Image&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;../shared/componentsWithStyles&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;AspectView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLayout&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;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;aspectRatio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputStyle&lt;/span&gt; &lt;span class="p"&gt;}&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;flatten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;inputStyle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;aspectRatio&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;layout&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;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;layout&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;width&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="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;width&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="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;aspectRatio&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;Image&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&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;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onLayout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://snack.expo.io/@bacon/aspectratio" rel="noopener noreferrer"&gt;Thank you &lt;code&gt;@baconbrix&lt;/code&gt; to share it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created an &lt;strong&gt;index.js&lt;/strong&gt; in the same folder (&lt;code&gt;src/components&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;AspectView&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;./AspectView&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;You can do the same with the folder &lt;code&gt;src/shared&lt;/code&gt; (create an &lt;strong&gt;index.js&lt;/strong&gt; file), but this is not the purpose of this post, you can improve on your own.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's dive into React Native
&lt;/h2&gt;

&lt;p&gt;You can create a file in the application root folder called &lt;strong&gt;app.json&lt;/strong&gt; to define some info about your app:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"expo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"PWAExpoWeb"&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;"A PWA using Expo Web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pwaingexpo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"privacy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"orientation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"portrait"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./assets/icon.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;"splash"&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;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./assets/splash.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;"resizeMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cover"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&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;"web"&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;"barStyle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"black-translucent"&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;Then, create an &lt;strong&gt;App.js&lt;/strong&gt; file on the root folder&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="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="nx"&gt;logo&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;./src/logo.svg&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;Code&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;@expo/html-elements&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;useDimensions&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-web-hooks&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;AspectView&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;./src/components&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;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;P&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="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;./src/shared/componentsWithStyles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;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="na"&gt;window&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDimensions&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;Container&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;Header&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;AspectView&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;height&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;P&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Edit &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;src/App.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; and save to reload.
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;P&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;A&lt;/span&gt;
              &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://reactjs.org"&lt;/span&gt;
              &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;
              &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"noopener noreferrer"&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Learn React
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;A&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;Header&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;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expo has a &lt;strong&gt;special configuration&lt;/strong&gt; so you need to set entrypoint in &lt;strong&gt;package.json&lt;/strong&gt;&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo/AppEntry.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continuing on &lt;strong&gt;package.json&lt;/strong&gt;, we need to add our scripts:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start"&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="s2"&gt;"expo start --android"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start --ios"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"eject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo eject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo build:web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"debug-prod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo build:web &amp;amp;&amp;amp; npx serve ./web-build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"now-build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn build &amp;amp;&amp;amp; expo-optimize"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you notice that after the &lt;code&gt;build&lt;/code&gt;, there is the &lt;code&gt;expo-optimize&lt;/code&gt;, so let's insert it on our project:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D sharp-cli expo-optimize expo-cli@3.13.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It's using specific version of &lt;strong&gt;Expo CLI (v3.13.0)&lt;/strong&gt; because, at the time of this post, the last version of the CLI was having a problem when being referenced by the Workbox, so, as a precaution, one of the last versions was added&lt;/p&gt;

&lt;p&gt;Last  but not least, we should increment some folders in &lt;code&gt;.gitignore&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#expo
.expo
web-build

#IDE
.idea
.vscode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;.expo:&lt;/strong&gt; Cache folder&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;web-build:&lt;/strong&gt; The web bundle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.idea &amp;amp; .vscode:&lt;/strong&gt; IDEs folders&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it, so you can try it running &lt;code&gt;yarn debug-prod&lt;/code&gt;. =-]&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy via Netlify or Now
&lt;/h2&gt;

&lt;p&gt;You can use this project as a Git repository, so on Netlify or Now, you can use the Github/Gitlab/Bitbucket repo synced with the &lt;code&gt;master&lt;/code&gt;. You have only to set the &lt;strong&gt;build command&lt;/strong&gt; as &lt;code&gt;yarn now-build&lt;/code&gt; and the &lt;strong&gt;output folder&lt;/strong&gt; as &lt;code&gt;web-build/&lt;/code&gt;, so everytime you push commit to master, it will be deployed in the services (Netlify/Now).&lt;/p&gt;

&lt;h2&gt;
  
  
  Whats next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Typescript - Expo has an incredible support for TS&lt;/li&gt;
&lt;li&gt;Workbox&lt;/li&gt;
&lt;li&gt;GraphQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;source: &lt;a href="https://github.com/mauriciord/pwa-expo-web" rel="noopener noreferrer"&gt;https://github.com/mauriciord/pwa-expo-web&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;demo: &lt;a href="https://pwa-expo-web.netlify.com/" rel="noopener noreferrer"&gt;https://pwa-expo-web.netlify.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;lighthouse: &lt;a href="https://googlechrome.github.io/lighthouse/viewer/?psiurl=https%3A%2F%2Fpwa-expo-web.netlify.com%2F&amp;amp;strategy=mobile&amp;amp;category=performance&amp;amp;category=accessibility&amp;amp;category=best-practices&amp;amp;category=seo&amp;amp;category=pwa&amp;amp;utm_source=lh-chrome-ext" rel="noopener noreferrer"&gt;https://googlechrome.github.io/lighthouse/viewer/?psiurl=https%3A%2F%2Fpwa-expo-web.netlify.com%2F&amp;amp;strategy=mobile&amp;amp;category=performance&amp;amp;category=accessibility&amp;amp;category=best-practices&amp;amp;category=seo&amp;amp;category=pwa&amp;amp;utm_source=lh-chrome-ext&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Thanks, 😎&lt;/p&gt;

</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>react</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Using cross tools with Expo Web and Native</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Tue, 03 Dec 2019 02:57:00 +0000</pubDate>
      <link>https://dev.to/expolovers/using-cross-tools-with-expo-web-and-native-3n81</link>
      <guid>https://dev.to/expolovers/using-cross-tools-with-expo-web-and-native-3n81</guid>
      <description>&lt;p&gt;first post of Expo series: &lt;a href="https://dev.to/atalkwithdev/resolving-expo-multi-select-photos-with-react-hooks-487k"&gt;https://dev.to/atalkwithdev/resolving-expo-multi-select-photos-with-react-hooks-487k&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing my series of posts about Expo, today we will discover how to use common development tools like &lt;strong&gt;Reactotron&lt;/strong&gt; and &lt;strong&gt;Sentry&lt;/strong&gt; in a cross-platform application using Expo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expo Web
&lt;/h2&gt;

&lt;p&gt;Let’s suppose that you’re going to build a Web version of your app (an Android/iOS app, but now you want a Web platform of this app), what would you do?&lt;/p&gt;

&lt;p&gt;First of all, let’s add a “web” option in the &lt;code&gt;app.json&lt;/code&gt; as a platform:&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="nl"&gt;"platforms"&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="s2"&gt;"ios"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-native-web react-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can just start your app :]&lt;/p&gt;

&lt;p&gt;Maybe you got an error from &lt;code&gt;./RCTNetworking&lt;/code&gt; that doesn’t leave your app starts. Probably you’ll get this error if you are already using &lt;strong&gt;Reactotron&lt;/strong&gt; solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing / Fixing Reactotron
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatalkwith.dev%2Fmedia%2Fscreen_shot_2019-12-01_at_22.45.44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatalkwith.dev%2Fmedia%2Fscreen_shot_2019-12-01_at_22.45.44.png" title="reactotron interface" alt="reactotron interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s install the &lt;strong&gt;Reactotron Client&lt;/strong&gt; at our machine following this &lt;a href="https://github.com/infinitered/reactotron/blob/master/docs/installing.md" rel="noopener noreferrer"&gt;installation guide&lt;/a&gt;. Then, we can create our files to each platform only writing the file extension prefix. &lt;em&gt;i.e.:&lt;/em&gt; &lt;code&gt;index.native.js&lt;/code&gt; and &lt;code&gt;index.web.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;*.web.js&lt;/code&gt; means that code will build and run only in the Web platform, the same approach is to the &lt;code&gt;*.native.js&lt;/code&gt;, but to the iOS/Android Platform.&lt;/p&gt;

&lt;p&gt;Create a folder called &lt;strong&gt;reactotron&lt;/strong&gt; on your app and then create the two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;index.native.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.web.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;index.native.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Reactotron&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openInEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;asyncStorage&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;reactotron-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;reactotronRedux&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;reactotron-redux&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;sagaPlugin&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;reactotron-redux-saga&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;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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;url&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;url&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="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NativeModules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SourceCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scriptURL&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;__DEV__&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;tron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Reactotron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;reactotronRedux&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;asyncStorage&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sagaPlugin&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;openInEditor&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useReactNative&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;tron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tron&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;
&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;reactotron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;native&lt;/span&gt; &lt;span class="nx"&gt;reactotron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;redux&lt;/span&gt; &lt;span class="nx"&gt;reactotron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;redux&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;saga&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;index.web.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Reactotron&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;reactotron-react-js&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;reactotronRedux&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;reactotron-redux&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;sagaPlugin&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;reactotron-redux-saga&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="nx"&gt;__DEV__&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Reactotron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;reactotronRedux&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sagaPlugin&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;tron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tron&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D reactotron-react-js reactotron-redux reactotron-redux-saga
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you have to add that configuration in somewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/your/reactotron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;span class="nf"&gt;registerRootComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppContainer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you build the app for Web, it will use the web configuration, if you build the app for Native, it will use the Native configuration.&lt;/p&gt;

&lt;p&gt;You will apply the same approach to Sentra tool, but you can follow this guide :]&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Sentry
&lt;/h2&gt;

&lt;p&gt;Unfortunately, there is a bug issue with Sentry Expo v.2.x with the Web Platform, then let’s use an older version, and let’s add the Sentry Browser to the Web Platform too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add sentry-expo@1.13.0 @sentry/browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, let’s configure our Sentry project, following the approach of the Reactotron, create a folder called &lt;strong&gt;sentry&lt;/strong&gt; on your app and then create the three files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sentry.native.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sentry.web.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;sentry.native.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Sentry&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;sentry-expo&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;env&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;path/to/your/constants/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SENTRY_PUBLIC_DNS&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;install&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;sentry.web.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Sentry&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;@sentry/browser&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;env&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;path/to/your/constants/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SENTRY_PUBLIC_DNS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;debug&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="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;index.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Sentry&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;./sentry&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="nx"&gt;Sentry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you want to use &lt;strong&gt;Sentry&lt;/strong&gt; to capture exceptions, you just import it:&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;Sentry&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;path/to/your/sentry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Sentry.captureException()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.expo.io/versions/latest/guides/using-sentry/" rel="noopener noreferrer"&gt;https://docs.expo.io/versions/latest/guides/using-sentry/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/getsentry/sentry" rel="noopener noreferrer"&gt;https://github.com/getsentry/sentry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/infinitered/reactotron" rel="noopener noreferrer"&gt;https://github.com/infinitered/reactotron&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forums.expo.io/t/sentry-api-does-not-work/27321/36" rel="noopener noreferrer"&gt;https://forums.expo.io/t/sentry-api-does-not-work/27321/36&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you enjoy this post, and soon I will post more about Expo and how to deliver a great value to your company and your clients using it.&lt;/p&gt;

&lt;p&gt;Thank you :]&lt;/p&gt;

</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Resolving Expo Multi Select Photos with React Hooks</title>
      <dc:creator>Mauricio Reatto Duarte</dc:creator>
      <pubDate>Thu, 21 Nov 2019 15:18:31 +0000</pubDate>
      <link>https://dev.to/expolovers/resolving-expo-multi-select-photos-with-react-hooks-487k</link>
      <guid>https://dev.to/expolovers/resolving-expo-multi-select-photos-with-react-hooks-487k</guid>
      <description>&lt;p&gt;Created: Nov 26, 2019 10:07 PM Tags: Expo, React Native, javascript&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Do you know the &lt;a href="https://expo.io"&gt;Expo&lt;/a&gt; project? Expo is a framework and a platform for universal React applications. It is a set of tools and services built around React Native and native platforms that help you develop, build, deploy, and quickly iterate on iOS, Android, and web apps from the same JavaScript/TypeScript codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflows
&lt;/h2&gt;

&lt;p&gt;The two approaches to building applications with Expo tools are called the “managed” and “bare” workflows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With the managed workflow you only write JavaScript / TypeScript and Expo tools and services take care of the rest for you.&lt;/li&gt;
&lt;li&gt;In the bare workflow, you have full control over every aspect of the native project, and Expo tools can’t help quite as much.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We won’t tell about the &lt;strong&gt;bare workflow&lt;/strong&gt; at this moment, only a problem with so many people using Expo SDK 33 or later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expo ImagePicker - launchImageLibraryAsync
&lt;/h2&gt;

&lt;p&gt;There is the &lt;code&gt;ImagePicker&lt;/code&gt; on the API for display the system UI for choosing an image or video from the phone’s library, but there isn’t a way to allow multiple selections of images, as you can see &lt;a href="https://docs.expo.io/versions/v35.0.0/sdk/imagepicker/#imagepickerlaunchimagelibraryasyncoptions"&gt;here&lt;/a&gt;. There are some feature requests here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expo.canny.io/feature-requests/p/allow-choosing-multiple-images-in-imagepicker"&gt;https://expo.canny.io/feature-requests/p/allow-choosing-multiple-images-in-imagepicker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://expo.canny.io/feature-requests/p/multiple-images-and-cameravideo-access-for-image-picker"&gt;https://expo.canny.io/feature-requests/p/multiple-images-and-cameravideo-access-for-image-picker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The solution with React Hooks
&lt;/h1&gt;

&lt;p&gt;In React Native, you can use the &lt;strong&gt;Camera Roll API&lt;/strong&gt; to get media from the phone’s library, then why not build a hook for that? :]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&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;CameraRoll&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;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="nx"&gt;useCameraRoll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;assetType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Photos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;groupTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;All&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPhotos&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="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;after&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAfter&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="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;hasNextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHasNextPage&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="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;getPhotos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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;hasNextPage&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;page_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pageInfo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CameraRoll&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPhotos&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;assetType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;groupTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;after&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="nx"&gt;after&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;pageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end_cursor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;setPhotos&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nx"&gt;setAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end_cursor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;setHasNextPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has_next_page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasNextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPhotos&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;After that, you simply use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// path to your hooks&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;useCameraRoll&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;shared/hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;SomeComponent&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;photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPhotos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCameraRoll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

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



&lt;p&gt;You can use &lt;code&gt;getPhotos&lt;/code&gt; in a &lt;code&gt;FlatList onEndReached&lt;/code&gt; props , for instance. Problem solved :]&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://facebook.github.io/react-native/docs/cameraroll.html"&gt;https://facebook.github.io/react-native/docs/cameraroll.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;https://reactjs.org/docs/hooks-intro.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;https://reactjs.org/docs/hooks-overview.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
