{"id":1801,"date":"2016-08-06T15:04:34","date_gmt":"2016-08-06T15:04:34","guid":{"rendered":"http:\/\/www.navision-blog.de\/blog\/?p=1801"},"modified":"2016-08-08T07:31:18","modified_gmt":"2016-08-08T07:31:18","slug":"fable-react-native","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2016\/08\/06\/fable-react-native\/","title":{"rendered":"Fable |> React Native &#8211; Native apps with F#"},"content":{"rendered":"<p><a href=\"#tldr\">TL;DR available<\/a> at the bottom of the post.<\/p>\n<h5>&#8220;A React Native App is a Real Mobile App&#8221;<\/h5>\n<blockquote><p>With React Native, you don&#8217;t build a &#8220;mobile web app&#8221;, an &#8220;HTML5 app&#8221;, or a &#8220;hybrid app&#8221;. You build a real mobile app that&#8217;s indistinguishable from an app built using Objective-C or Java. React Native uses the same fundamental UI building blocks as regular iOS and Android apps. You just put those building blocks together using JavaScript and React. [<a href=\"https:\/\/facebook.github.io\/react-native\/\">project site<\/a>]<\/p><\/blockquote>\n<p>That doesn&#8217;t sound too bad, but why do we have to do it in JavaScript?<\/p>\n<p>Well, this article shows that we don&#8217;t have to.<\/p>\n<h5>The nightwatch app<\/h5>\n<p>Consider you are working for some kind of Nightwatch and it&#8217;s getting dark and your watch is about to begin.<\/p>\n<p>The nice people of your order gave you a phone and a new app. At the beginning of the night it downloads a list with locations that you have to check. Every location can be marked as OK or you can blow a virtual horn to trigger an alarm. The app also allows you to append an photo of the situation on the ground.<\/p>\n<p>Since many of the locations that you will visit are far away from good internet connection the app stores everything locally on your phone. Once in a while it will sync with the nightwatch central.<\/p>\n<p>So this could look a bit like this:<\/p>\n<p><img src=\"http:\/\/www.navision-blog.de\/images\/nightwatchapp.gif\" alt=\"Nightwatch app\" \/><\/p>\n<p>So now after embaressing myself and\u00a0showing my design skills, let&#8217;s jump into the technical stuff.<\/p>\n<h5>Developing with F# in VS Code<\/h5>\n<p>The app was developed with <a href=\"http:\/\/fsharp.org\/\">F#<\/a> in <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a>\u00a0(with <a href=\"http:\/\/ionide.io\/\">ionide<\/a> and <a href=\"https:\/\/github.com\/Microsoft\/vscode-react-native\">react native<\/a> plugins). This development environment\u00a0runs on all platforms, so you can use\u00a0Windows, Linux or your Mac.<\/p>\n<p><a href=\"http:\/\/www.navision-blog.de\/images\/hotloading.gif\"><img src=\"http:\/\/www.navision-blog.de\/images\/hotloading_small.gif\" alt=\"Hotloading F# code\" \/><\/a><\/p>\n<p>As you can see we have a React Native app with\u00a0<a href=\"https:\/\/facebook.github.io\/react-native\/blog\/2016\/03\/24\/introducing-hot-reloading.html\">automatic loading<\/a> of compiled F# code.<\/p>\n<p>The big difference to using JavaScript is that everything is statically typed &#8211; even the access to the JavaScript APIs. This gives you nice autocomplete features and depending on the concrete bindings you can even get documentation in the editor:<\/p>\n<p><a href=\"http:\/\/www.navision-blog.de\/images\/flex.gif\"><img src=\"http:\/\/www.navision-blog.de\/images\/flex_small.gif\" alt=\"Autcomplete in F# code\" \/><\/a><\/p>\n<p><a href=\"https:\/\/twitter.com\/k_cieslak\">Krzysztof Cie\u015blak<\/a> did really amazing work with the <a href=\"https:\/\/github.com\/ionide\">Ionide<\/a> &#8211; this tooling works pretty well. Take a look at his <a href=\"http:\/\/kcieslak.io\/\">blog<\/a> to find out more about the awesomeness that he brings to the ecosystem. He also played an important part in\u00a0getting React Native to work with F#.<\/p>\n<h5>Introducing Fable<\/h5>\n<p><a href=\"&quot;http:\/\/fsprojects.github.io\/Fable\/\">Fable<\/a> is the most important technology behind all of this. It was designed by <a href=\"https:\/\/twitter.com\/alfonsogcnunez\">Alfonso Garcia-Caro<\/a>\u00a0as a F# to JavaScript compiler and can do real magic in the browser. Take the time and <a href=\"https:\/\/www.youtube.com\/watch?v=iP-50fj06Eo\">watch the 10min intro<\/a>. I can&#8217;t stress enough how well this open source project is managed. It&#8217;s\u00a0a real pleasure to be part of it now.<\/p>\n<p>In our case it bridges React Native APIs into F# and also compiles the F# code back to JavaScript whenever we save a file. The React Native framework is listening for the changes in the JavaScript files and swaps the code in the device simulator. There is a lot going on behind the scenes, but it&#8217;s already working surprisingly well.<\/p>\n<h5>Using\u00a0JavaScript APIs<\/h5>\n<p>Since most of the React Native APIs are developed in JavaScript it&#8217;s important to bring these APIs over to F#. This is done as\u00a0a community effort and the Fable project creates typed JavaScript bindings for many\u00a0major JavaScript frameworks. This effort is comparable to <a href=\"http:\/\/definitelytyped.org\/\">DefinitelyTyped<\/a> in the TypeScript world. There is even a tool that can help to convert TypeScript bindings to Fable bindings.<\/p>\n<p>In our case the <a href=\"https:\/\/www.npmjs.com\/package\/fable-import-react-native\">fable-import-react-native<\/a>\u00a0is the most important package. It provides typed bindings to most of the React Native APIs.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/forki\/6752c56a6cb6dae5015567097ee0b80f.js\"><\/script><\/p>\n<p>This snippet creates a <a href=\"https:\/\/facebook.github.io\/react-native\/docs\/view.html\">View component<\/a>\u00a0in React Native and puts two buttons inside it.<\/p>\n<h5>Using F#<\/h5>\n<p>One nice benefit of this model is that we can use\u00a0ordinary, statically typed F# code for our app. In the demo project you can find a small F# domain model:<br \/>\n<script src=\"https:\/\/gist.github.com\/forki\/16065bde7e4f00efcdbe678e4fe9dfe9.js\"><\/script><\/p>\n<p>If you are interested in learning the language then I recommend to look at website of the <a href=\"http:\/\/fsharp.org\/\">F# software foundation<\/a>. For <a href=\"https:\/\/fsharpforfunandprofit.com\/ddd\/\">domain driven design in F#<\/a>\u00a0you can find excellent articles on\u00a0a site called &#8220;<a href=\"https:\/\/fsharpforfunandprofit.com\/\">F# for fun and profit<\/a>&#8220;.<\/p>\n<h5>Access to native components<\/h5>\n<p>React Native allows you to access native phone components like the camera. Most of these APIs are written in a mix of Java\/ObjectiveC and JavaScript. Given the Fable bindings are already present it&#8217;s super easy to access the same APIs from F#. In the following sample we access a nice ImagePicker via the <a href=\"https:\/\/www.npmjs.com\/package\/fable-import-react-native-image-picker\">fable-import-react-native-image-picker bindings<\/a>:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/forki\/3330c3492616ef22151702a6b7e8c400.js\"><\/script><\/p>\n<p>This ImagePicker is distributed via a separate npm package, but it&#8217;s API feels like the rest of the React Native functions. We can provide some properties and a callback &#8211; and everything is statically typed so that we have autocompletion in VS Code.<\/p>\n<h5>Data storage<\/h5>\n<p>For most apps you want to have some local storage in order to cache information. React Native provides a basic abstraction called <a href=\"https:\/\/facebook.github.io\/react-native\/docs\/asyncstorage.html\">AsyncStorage<\/a> that works on Android and iOS. With the help of a package called <a href=\"https:\/\/www.npmjs.com\/package\/fable-react-native-simple-store\">fable-react-native-simple-store<\/a> we can use it from F#:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/forki\/aa0dfeeef700a7c9e7abe6c60705502a.js\"><\/script><\/p>\n<p>As you can see all function in this storage model are asynchronous and with the help of the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/visualfsharpdocs\/conceptual\/asynchronous-workflows-%5Bfsharp%5D\">async computation expressions<\/a>\u00a0they become really easy to use in F#.<\/p>\n<h5>Web access<\/h5>\n<p>Another advantage of\u00a0React Native is the huge ecosystem you see on <a href=\"https:\/\/www.npmjs.com\/\">npm<\/a>.\u00a0In our app we want to retrieve a list with locations that we need to check. This list is just a bit of JSON on a http resource. With the help of a very popular JavaScript package called <a href=\"https:\/\/www.npmjs.com\/package\/fetch\">fetch<\/a> and the corresponding\u00a0<a href=\"https:\/\/www.npmjs.com\/package\/fable-import-fetch\">fetch-bindings<\/a>\u00a0(written by <a href=\"http:\/\/7sharpnine.com\/\">Dave Thomas<\/a>)\u00a0we can write something like this:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/forki\/f94e53d8298aa96abad05ef88d0e3d55.js\"><\/script><\/p>\n<p>So we see the same async model here and everything fits nicely together.<\/p>\n<h5>Project status<\/h5>\n<p>The project with the working title\u00a0<a href=\"https:\/\/github.com\/fsprojects\/fable-react_native-demo\">&#8220;Fable |&gt; React Native&#8221;<\/a> is currently considered &#8220;highly experimental&#8221;. APIs and JavaScript bindings are not complete and likely to break multiple times.<\/p>\n<p>In general the <a href=\"https:\/\/github.com\/fsprojects\/Fable\">Fable project<\/a> is shaping things up for a v1.0 release. So sharing experiences, comments and bug reports with the Fable compiler and APIs is appreciated.<\/p>\n<p>Debugging of the react native apps is currently only working in\u00a0the generated JavaScript.\u00a0With\u00a0the next release of the<a href=\"https:\/\/github.com\/Microsoft\/vscode-react-native\"> VS Code react native extension<\/a>\u00a0we will <a href=\"https:\/\/github.com\/Microsoft\/vscode-react-native\/issues\/240#issuecomment-224778918\">probably be able to set breakpoints directly in the\u00a0F# source<\/a>.<\/p>\n<p>That said, it already feels very very productive and if you are interested in this kind of mobile development then check out the <a href=\"https:\/\/github.com\/fsprojects\/fable-react_native-demo\">sample project<\/a> and follow\u00a0how it develops over time. There is even a similar approach that allows you to use <a href=\"http:\/\/7sharpnine.com\/blog\/Light-The-Fuse\/\">F# on fuse<\/a>,\u00a0so I think we will probably see a lot of choice in the future.<\/p>\n<h5><a name=\"tldr\"><\/a>TL;DR for F# devs<\/h5>\n<p>With this model you can start to develop Android and iOS apps on the <a href=\"https:\/\/facebook.github.io\/react-native\/\">react native<\/a> model\u00a0while still keeping most of the type safety and tooling. Using <a href=\"http:\/\/fsprojects.github.io\/Fable\/\">fable<\/a>\u00a0gives you access to a huge ecosystem with JavaScript libraries and frameworks. Check out the <a href=\"https:\/\/github.com\/fsprojects\/fable-react_native-demo\">sample project<\/a>\u00a0and follow the instructions in the Readme.<\/p>\n<h5>TL;DR for JavaScript devs<\/h5>\n<p>If you like creating apps with the\u00a0<a href=\"https:\/\/facebook.github.io\/react-native\/\">React Native<\/a> model, but it always felt a bit hard to maintain JavaScript, then this might be interesting for you. With this approach you can apply all your knowledge and use it from a excellent type safe language with amazing autocompleting tooling.<\/p>\n<p>With one or two tricks you can even reuse many\u00a0of the npm libraries that you know and love. Check out the <a href=\"https:\/\/github.com\/fsprojects\/fable-react_native-demo\">sample project<\/a>\u00a0and follow the instructions in the Readme.<\/p>\n<h5>TL;DR for TypeScript devs<\/h5>\n<p>You have already left the path of plain JavaScript. Maybe you are ready to leave it a bit further\u00a0and to investigate different languages like <a href=\"http:\/\/elm-lang.org\/\">Elm<\/a> or <a href=\"http:\/\/www.purescript.org\/\">PureScript<\/a>. If this is you then\u00a0check out the <a href=\"https:\/\/github.com\/fsprojects\/fable-react_native-demo\">sample project<\/a>\u00a0and follow the instructions in the Readme. It shows you how a language like F# can help you to work with JavaScript APIs.<\/p>\n<h5>TL;DR for C# devs<\/h5>\n<p>Sorry, nothing to see here.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR available at the bottom of the post. &#8220;A React Native App is a Real Mobile App&#8221; With React Native, you don&#8217;t build a &#8220;mobile web app&#8221;, an &#8220;HTML5 app&#8221;, or a &#8220;hybrid app&#8221;. You build a real mobile app that&#8217;s indistinguishable from an app built using Objective-C or Java. React Native uses the same [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,448,8],"tags":[534,672,671,673],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1801"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=1801"}],"version-history":[{"count":59,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1801\/revisions"}],"predecessor-version":[{"id":1860,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1801\/revisions\/1860"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=1801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=1801"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=1801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}