Writing multi-platform mobile apps with React Native and KotlinJS

Image for post

Kotlin is an awesome language. It is functional and offers extension functions, null safety, smart casting, type-safe builders, default and named arguments, data classes and much more. It is arguably the language of choice for Android developers and very familiar to iOS developers.

React Native enables us to write only once for multiple platforms, has a simpler API than native development and a smooth learning curve. Steve Yegg, a former Google engineer, conjectures in his blog post that hybrid frameworks are likely to become even more popular. And the framework from Facebook is the major player at the moment.

So why not mixing both? 
Standing on the shoulder of giants (JetBrains/kotlin-wrappers and ScottPierce/kotlin-react-native), we can. 
An example repository can be found here.

React in a nutshell

You can learn the basics of React Native very quickly reading the official tutorial, but three important takeaways are:

  • view = f(state) 
  • React has a virtual representation of the view, and it calculates the smallest diff between renders
  • development should be component-driven

Hello world in Kotlin

After cloning the example repository and following the README, you can simply edit the render() function to immediately see the result on the device.

For example, writing the following code…

…would render the following output:

Image for post
Our first application with Kotlin and React Native

Thanks to the Kotlin language features, we can write the view using a builder DSL similar to JSX, instead of manually calling React.createElement(…, React.createElement(…)).

Creating our first component

Let’s say you have the following view architecture and you want to make the code for headers reusable:

For this task, you could create a Header component:

And call it from the render() function as such:

Alternatively, if you want the extend the DSL so that you can call this component directly, just create an extension function:

Managing state

React doesn’t dictate how state management should be. For the sake of this example, let’s write our own simplified, naive implementation of Redux.

In this pattern, we have three main elements:

  • store: holds the state
  • actions: describe the changes
  • reducers: return an updated state based on the requested action

Here is the full implementation:

Evidently, on a real world application, you should prevent race conditions and implement the subscriptions in an atomic fashion, possibly using RxJS. But that’s good for now.

A less contrived example

Now let’s write a simple application which consists of a header, and two rating widgets, for giving scores to two different programming languages.

First we create the models:

Then the actions that can be dispatched:

Later on, we define the reducer:

Then we define a view model, mapping state to view abstractions:

We connect everything with a store:

Finally, we create a stateless, dumb component:

And another component that keeps track of the state:

And the final result is:

Image for post
Our final application

So… Is Kotlin with React Native production-ready?

Possibly, but there are still some improvements to be made to the whole ecosystem. The interoperability with JavaScript isn’t effortless and has some pitfalls. For example, passing the store via props to the component won’t work because the state will become immutable. Also, using data classes for the props directly will return an error from React because apparently the serialization contains some metadata. In addition, you’re supposed to write your own type definitions, which is a huge productivity killer.

I think JetBrains is to blame for the unpopularity of KotlinJS, by not giving the language the love it deserves. Kotlin/ts2kt, for instance, could solve the type definition problem. However, most of the attempts for converting types fail, and the issues remain open. Actually, we don’t see many examples targeting JS at all, despite the fact that this a working platform for more than a year. Maybe they are focused on Kotlin/Native

In the meantime, another alternative to JavaScript is Clojurescript, which is awesome with re-frame and in my opinion offers the best development experience out there. However, it’s not for the faint-hearted.

I hope that with this article and the example repository, the community can reconsider Kotlin as a language for React Native. Feel free to fork the code!

This post first appeared on Medium.