Why I left Xamarin behind in favor of React Native
Being a developer is an ongoing fight with the tools, languages and bugs. In this series I write about my everyday challenges as a software developer.
Xamarin: the Good, the Bad, and the Ugly
I have used Xamarin, formerly Mono.Touch and Mono.Android, for more than four years in many client projects for small prototypes as well as large B2B applications. And I was always happy, or let me say: it was the best for its time.
.NET. I love C#, it’s a handy and powerful language. With more than 6 years experience in developing with .NET, Xamarin felt always right for me. And you maybe remember, a couple of years ago the only real alternative for creating mobile cross-platform apps was Cordova / PhoneGap. But this was no alternative, because of the miserable user-experience.
Native APIs. For developers with a strong .NET background the APIs are natural and you can still adopt examples from Java or ObjectiveC with ease. All official SDKs are provides on the same-day for Xamarin as for Android and iOS, at least in the beta channel. Some companies also provide Xamarin SDKs in addition to Android/iOS. And, those which are not available, can be bridged from an existing jar/pod. Not to forget, that this all could be done with Visual Studio and no need of a crappy XCode or something else, beside the Mac Build Host in your drawer. (🔔 Shame on you Apple and your stupid licence models)
Xamarin.Forms. Later on, Xamarin introduced Xamarin.Forms as possibility to create simple cross-platform UIs with native feeling on every platform. As long as you stay with some simple B2B apps it’s a good way to save some development time, as long as you only want iOS and Android. It is quite funny to mention that XAML for Xamarin.Forms has more features than XAML for UWP.
All in all we have C#, native performance, native UI and the ability to bridge all jars/pods into our project. So, why not stay with Xamarin?
Deployment time! For experienced developers it is bearable that it took up to five minutes between pressing F5 and emerging on the screen. They’re often writing code for hours and are sure-footed that it will always work as expected as long it compiles. We all know that this is a double-edged sword. Especially for inexperienced developers the feedback loop is way to long. They need to check even small code changes if they work as expected. You can imagine that it is frustrating if you spend 80 percent of your time waiting for Visual Studio compiling your project, sending it to your smartphone, only to see that it crashed. Again.
No Preview! Have you ever worked together with a UI/UX designer, who is a real pixel-nazi? Than you may know, that “Let Xamarin align it somehow” is not an adoptable way to do user interfaces. And, even if you do your very best and align everything like it’s measured in the design, it will look like on the design. Especially, fonts are rendered different on each platform and always need to be amended manually. OK, Visual Studio for Mac (just a renamed Xamarin Studio) has a design preview for Android/iOS but it’s not working very well if you use lot’s of DataBinding and no static UI composition. The WPF Preview in Visual Studio 2015 or previously in Expression Blend was head and shoulders better.
Before, someone of you bring in these argument: We could check a lot of use-cases with unit tests. Therefore, we only need to deploy to a device if we absolutely need to check the all-together. This is feasible for large project but not for rapid development and prototypes. Similar for the preview. We can create the UI with static content and after everything is as we expect we change to dynamic content. This is right for large enterprise application where the whole product is shipped at once, but not applicable where the UI/UX evolves agile with its features.
Native Binding. The idea is awesome. Jars also worked mostly well, but I hope you have never needed to bridge a Cocoa Pod with multiple dependencies into your project. It’s like building an IKEA wardrobe with missing pieces and a Chinese manual. You can trust me, it will not work out of the box. Xamarin is providing us a tool called Sharpie (the Chinese manual) which helps a little, but the documentation did not even work with the most easiest pods. If you have mastered the first step to compile the pod and generate the bindings, you will spent a whole day correcting the guesses of Sharpie and remove the not compile-able attributes. If you ever need help bridging a pod into you project, ping me.
Portable Class Libraries. It appeared as the coolest idea back in 2013 when Xamarin added PCL support, but it turned out to become developers worst nightmare. We ended up with 44 different PCL profiles and a stunning multidimensional matrix defining, which are compatible with each other and which not. A solution was to always target 328 and use a bait-switch trick. Unfortunately, this either ended in lots of duplicated code or thousands of compiler flags, which is both terrible to debug. Now, we have .NET Standard which seems to be the light at the end of the tunnel, and I keep my fingers crossed that it’s not an oncoming train.
Native-Renderer. Also a nifty idea to create native components for a xplat context. And, for a simple B2B App, which uses only default UI components, it is an easy way to add something which is not expected by the Xamarin.Forms authors. Each UI element itself behaves like it should, but unfortunately the interplay between the UI elements often result in strange unpredictable effects. Native Renderer are also difficult to implement for newbies and can become performance hungry if the developers do not have a deep understanding of the platform.
All these little edges, joined by regular crashes and unpredictable expressionless exceptions, I decided to jump out of my comfort zone and keep my eyes open for an alternative.
React-Native: A whole new Universe
Three weeks ago, I gave an introduction to Xamarin for students at a hackathon in Berlin. And Xamarin operates as always. It crashed. I don’t need to bring up that the students were not keen to start using Xamarin in their projects. This was the tie-breaking vote to search deep for an alternative. I have always looked over the rim of the tea cup, but all other main-stream alternatives like Cordova are a real usability nightmares which are at most good enough for a company intern survey app.
A framework for easily creating beautiful presentations using HTMLdjcordhose.github.io
I don’t want to argue here, why plain js was not an acceptable choice. But, if you want to discuss it, send me a pm. I’m also open for good arguments in favor of Flowtype.
One week later, with almost no sleep and half a dozen buckets of coffee, I ported our existing prototype to react-native and TypeScript. At the beginning, it was challenging, but after some more deep diving I enjoyed developing with react-native. To be honest, if you are completely new to the whole npm system, it feels like cleaning your house with a toothbrush. It becomes more dirty, while cleaning. But, here are the biggest benefits I see in react-native.
Hot-Module-Replacement. The absolute killer feature of react-native. As long as you do not change a native dependency of your app, which happens almost never, you don’t need to compile anything. The code is replaced, as soon as you save the source code. All app-state is kept and you see every change live. Regardless, if you test it in the emulator or on a real device or both at once. This decreased the feedback loop to a minimum and the learning curve raised exponential.
Code-Push. If you do not know code-push you’re missing an absolute must have tool for react-native. Code-push allows you to deploy your app to your clients within minutes and past the app stores. You can deploy much faster than ever and even to A/B test with ease, since you can control how multiple versions are spread to your clients.
Less compiler directives. One thing I definitely love in comparison to Xamarin is how they are handling differences between iOS and Android. First, you can call some iOS and Android specific method to use features which are not available on the other platforms. Second, you do not need to embrace them with compiler directives, because they just do nothing if called on the other platform. Best example is, that you set shadow properties for views on iOS and elevation for views on Android. You can put both on the same style sheet without notice. And, if you really need to, you can even drop native Java / Swift code into your app with ease.
My journey with react-native had only just begun. I will keep you up to date with my experiences.
If you liked this give me a 💗 and share the tweet below. I am also curious to read your opinions about Xamarin, react-native and mobile development in general.