<?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: Mateusz Zatorski</title>
    <description>The latest articles on DEV Community by Mateusz Zatorski (@matzatorski).</description>
    <link>https://dev.to/matzatorski</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%2F125212%2F4f928b34-0f45-4aca-a45c-a7924cabd2f4.jpg</url>
      <title>DEV Community: Mateusz Zatorski</title>
      <link>https://dev.to/matzatorski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matzatorski"/>
    <language>en</language>
    <item>
      <title>Building type-safe mobile apps with Expo and ReasonML (part 1)</title>
      <dc:creator>Mateusz Zatorski</dc:creator>
      <pubDate>Tue, 15 Sep 2020 19:29:21 +0000</pubDate>
      <link>https://dev.to/matzatorski/building-type-safe-mobile-apps-with-expo-and-reasonml-part-1-4ck6</link>
      <guid>https://dev.to/matzatorski/building-type-safe-mobile-apps-with-expo-and-reasonml-part-1-4ck6</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;span&gt;Cover Photo by &lt;a href="https://unsplash.com/@kellysikkema?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Kelly Sikkema&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/mobile?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;These blog posts assume that you are familiar with React and React Native. For simplicity, I will also use &lt;a href="https://docs.expo.io/"&gt;Expo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also assume that you already know the benefits of using ReasonML. If not I highly recommend checking &lt;a href="https://reasonml.github.io/docs/en/what-and-why#why-reason"&gt;ReasonML docs&lt;/a&gt; or old but still very relevant &lt;a href="https://medium.com/@johnhaley81/why-reasonml-part-1-8a975bbcf5f7"&gt;"Why ReasonML?"&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 1: Expo + ReasonML setup
&lt;/h1&gt;

&lt;p&gt;This is the first part of the blog post series about building a mobile app with the use of Expo and ReasonML. The main focus on in this part is on setting up the project and writing the first component in ReasonML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started
&lt;/h2&gt;

&lt;p&gt;In order to be able to use ReasonML in our Expo app, we will need to add BuckleScript (now known as &lt;a href="https://rescript-lang.org/#why-the-rebrand"&gt;ReScript&lt;/a&gt;). It is needed to compile the ReasonML/ReScript code to JavaScript.&lt;/p&gt;

&lt;p&gt;We will also need React Native bindings. I will talk more about bindings in the upcoming blog post of this series. Bindings allow for a typed interface between JavaScript code and your code in ReasonML.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create an Expo app
&lt;/h2&gt;

&lt;p&gt;First, let's start with creating the Expo app (in case you do not have Expo installed check out &lt;a href="https://docs.expo.io/get-started/installation/"&gt;the docs&lt;/a&gt;):&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;# Create a new project&lt;/span&gt;

expo init my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the next step Expo will ask you what template to use:&lt;/p&gt;

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

&lt;p&gt;I would recommend using the blank (Typescript) template from the Managed workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add ReasonML
&lt;/h2&gt;

&lt;p&gt;Instructions on how to add Reason React Native to your current project can be followed here: &lt;a href="https://reason-react-native.github.io/en/docs/install"&gt;https://reason-react-native.github.io/en/docs/install&lt;/a&gt; (under "Add Reason React Native to an existing project").&lt;/p&gt;

&lt;p&gt;Or you can follow the steps below:&lt;/p&gt;

&lt;h3&gt;
  
  
  add the dependencies
&lt;/h3&gt;

&lt;p&gt;As previously mentioned we will need BuckleScript, Reason React and Reason React Native bindings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add bs-platform &lt;span class="nt"&gt;--dev&lt;/span&gt;
yarn add reason-react reason-react-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  create &lt;code&gt;bsconfig.json&lt;/code&gt; in the root of the project
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;bsconfig.json&lt;/code&gt; is a configuration file used by ReScript (former BuckleScript)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"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;"my-reason-react-native-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;"refmt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&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;"react-jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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;"package-specs"&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;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"in-source"&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="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;"suffix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".bs.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dir"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"subdirs"&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="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bs-dependencies"&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;"reason-react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reason-react-native"&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;
  
  
  create &lt;code&gt;src&lt;/code&gt; directory and add &lt;code&gt;App.re&lt;/code&gt; into &lt;code&gt;src&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;App.re&lt;/code&gt; we will create our first component in using ReasonML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight reasonml"&gt;&lt;code&gt;&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nc"&gt;ReactNative&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="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello from ReasonML!"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;🎉&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;})}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  add scripts to &lt;code&gt;package.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let's add three scripts that will allow us to build, clean and build in a watch mode our ReasonML code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"re:build": "bsb -clean-world -make-world",
"re:watch": "bsb -clean-world -make-world -w",
"re:clean": "bsb -clean-world"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  edit &lt;code&gt;App.tsx&lt;/code&gt; in the root of the project
&lt;/h3&gt;

&lt;p&gt;Expo project comes with an initial &lt;code&gt;App.tsx&lt;/code&gt; we will edit it to use the &lt;code&gt;App.re&lt;/code&gt; from &lt;code&gt;src&lt;/code&gt; directory as our root component:&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="nx"&gt;make&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;default&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/App.bs.js&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;We import the &lt;code&gt;App.bs.js&lt;/code&gt; file as this is the file that gets created by ReScript compiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Run the app
&lt;/h2&gt;

&lt;p&gt;In one terminal let's run the ReScript compiler in the watch mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn re:watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the other run the Expo app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  4. Summary
&lt;/h2&gt;

&lt;p&gt;Adding the ability to write ReasonML isn't hard so give it a try and see for yourself what benefits it can bring to your project!&lt;/p&gt;

&lt;p&gt;I created a small helper - &lt;a href="https://github.com/mlventures/expo-reason-starter"&gt;Expo ReasonML Starter&lt;/a&gt; so there's no need to go through these steps every time you want to build a new app in Expo.&lt;/p&gt;

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

&lt;p&gt;In the end, I made it even easier to so you can start building your app with just one expo init command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;expo init &lt;span class="nt"&gt;-t&lt;/span&gt; expo-template-rescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need more details or want to improve the template, here's the repo: &lt;a href="https://github.com/mlventures/expo-template-rescript"&gt;https://github.com/mlventures/expo-template-rescript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's coming next:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;building an actual app with ReasonML (making use of most common React Native components and API)&lt;/li&gt;
&lt;li&gt;writing bindings&lt;/li&gt;
&lt;li&gt;in case there's anything else you'd like to see in this series, please comment below or ping me on &lt;a href="https://twitter.com/matzatorski"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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