Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Saturday, 6. August 2016


Fable |> React Native – Native apps with F#

Filed under: .NET,F#,Informatik — Steffen Forkmann at 15:04 Uhr

TL;DR available at the bottom of the post.

“A React Native App is a Real Mobile App”

With React Native, you don’t build a “mobile web app”, an “HTML5 app”, or a “hybrid app”. You build a real mobile app that’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. [project site]

That doesn’t sound too bad, but why do we have to do it in JavaScript?

Well, this article shows that we don’t have to.

The nightwatch app

Consider you are working for some kind of Nightwatch and it’s getting dark and your watch is about to begin.

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.

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.

So this could look a bit like this:

Nightwatch app

So now after embaressing myself and showing my design skills, let’s jump into the technical stuff.

Developing with F# in VS Code

The app was developed with F# in Visual Studio Code (with ionide and react native plugins). This development environment runs on all platforms, so you can use Windows, Linux or your Mac.

Hotloading F# code

As you can see we have a React Native app with automatic loading of compiled F# code.

The big difference to using JavaScript is that everything is statically typed – 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:

Autcomplete in F# code

Krzysztof CieÅ›lak did really amazing work with the Ionide – this tooling works pretty well. Take a look at his blog to find out more about the awesomeness that he brings to the ecosystem. He also played an important part in getting React Native to work with F#.

Introducing Fable

Fable is the most important technology behind all of this. It was designed by Alfonso Garcia-Caro as a F# to JavaScript compiler and can do real magic in the browser. Take the time and watch the 10min intro. I can’t stress enough how well this open source project is managed. It’s a real pleasure to be part of it now.

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’s already working surprisingly well.

Using JavaScript APIs

Since most of the React Native APIs are developed in JavaScript it’s important to bring these APIs over to F#. This is done as a community effort and the Fable project creates typed JavaScript bindings for many major JavaScript frameworks. This effort is comparable to DefinitelyTyped in the TypeScript world. There is even a tool that can help to convert TypeScript bindings to Fable bindings.

In our case the fable-import-react-native is the most important package. It provides typed bindings to most of the React Native APIs.

This snippet creates a View component in React Native and puts two buttons inside it.

Using F#

One nice benefit of this model is that we can use ordinary, statically typed F# code for our app. In the demo project you can find a small F# domain model:

If you are interested in learning the language then I recommend to look at website of the F# software foundation. For domain driven design in F# you can find excellent articles on a site called “F# for fun and profit“.

Access to native components

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’s super easy to access the same APIs from F#. In the following sample we access a nice ImagePicker via the fable-import-react-native-image-picker bindings:

This ImagePicker is distributed via a separate npm package, but it’s API feels like the rest of the React Native functions. We can provide some properties and a callback – and everything is statically typed so that we have autocompletion in VS Code.

Data storage

For most apps you want to have some local storage in order to cache information. React Native provides a basic abstraction called AsyncStorage that works on Android and iOS. With the help of a package called fable-react-native-simple-store we can use it from F#:

As you can see all function in this storage model are asynchronous and with the help of the async computation expressions they become really easy to use in F#.

Web access

Another advantage of React Native is the huge ecosystem you see on npm. In 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 fetch and the corresponding fetch-bindings (written by Dave Thomas) we can write something like this:

So we see the same async model here and everything fits nicely together.

Project status

The project with the working title “Fable |> React Native” is currently considered “highly experimental”. APIs and JavaScript bindings are not complete and likely to break multiple times.

In general the Fable project is shaping things up for a v1.0 release. So sharing experiences, comments and bug reports with the Fable compiler and APIs is appreciated.

Debugging of the react native apps is currently only working in the generated JavaScript. With the next release of the VS Code react native extension we will probably be able to set breakpoints directly in the F# source.

That said, it already feels very very productive and if you are interested in this kind of mobile development then check out the sample project and follow how it develops over time. There is even a similar approach that allows you to use F# on fuse, so I think we will probably see a lot of choice in the future.

TL;DR for F# devs

With this model you can start to develop Android and iOS apps on the react native model while still keeping most of the type safety and tooling. Using fable gives you access to a huge ecosystem with JavaScript libraries and frameworks. Check out the sample project and follow the instructions in the Readme.

TL;DR for JavaScript devs

If you like creating apps with the React Native 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.

With one or two tricks you can even reuse many of the npm libraries that you know and love. Check out the sample project and follow the instructions in the Readme.

TL;DR for TypeScript devs

You have already left the path of plain JavaScript. Maybe you are ready to leave it a bit further and to investigate different languages like Elm or PureScript. If this is you then check out the sample project and follow the instructions in the Readme. It shows you how a language like F# can help you to work with JavaScript APIs.

TL;DR for C# devs

Sorry, nothing to see here.

Tags: , , ,