Posts Using Xamarin-Fabulous in enterprise

Using Xamarin-Fabulous in enterprise

Providing some context

I work for a small-to-mid-sized company (~200 employees) that deals with compliance and tax compliance. The company had a mobile app that replaced paper records of work. The app was not in good shape, though, and needed a re-write. While the rest of the company used Java, this app was written in C# using Xamarin. The company had a newer app that also used C# with a tiny bit of F#.

Fabulous looked like the perfect candidate for this new app. At the time, though, Fabulous had not been out for long (this was the end of 2018). Also, this would be a full app in F#, not just a bit on the side. How would the rest of the company feel?

What follows is a brief story of how a small team wrote an F# mobile app in a company with mostly Java developers.


Very early on, I was the only one in the team and the single mobile developer in the company. I needed more support to make anything happen.

I found support from a couple of product managers. I focused on aligned interests - helping customers and building great products. The essence of agile is a mix of skill sets to aid in delivery.

Small Steps

With the help of the product-managers, the company proved me two-weeks to build a prototype app as a proof-of-concept (POC). When adopting new technology (that high-level execs are not concerned about), it is wise to be cautious. Going into full-scale development would have been far too risky if Fabulous was not ready.

The POC worked out well. It identified a few areas where Fabulous was a bit weak (more on that later). One of the product managers and I demonstrated what we had achieved in the two weeks to a few non-technical people. I did not find any significant problems with Fabulous, and other technical people saw no issues, so Fabulous was selected for the app re-write.

Full-Scale development

One of the product managers continued with the project. They provided support for a business case to replace things. Businesspeople didn’t care too much about the technology. Using Fabulous in the app was only possible with the help of these non-technical individuals.

I started development on the app, and then something interesting happened. Word spread around the company that I was using functional programming. Many didn’t care for this, some observed, and another liked the idea, so joined the team. Recruitment for development was successful.

Fast-forward some time, and the team had added complex business rules to the app. During this time, more recruitment had taken place, and two more people joined our crew.

Start spreading

The team had completed most of the development of the mobile app. There were a few changes in the company, and time had come to build out the backend. The original idea was to use Java. It seemed like the logical choice as most developers knew Java. However, there was no Java developer in our crew. We all knew F#.

It was time to spread F# to the backend. F# is even better at backend too. To fit into the companies tech stack, the team and I had to do some creative thinking. The company had written most of the system with Java or the JVM in mind. We pulled it off, but I’ll leave the details for the backend for another post (leave a comment you would like to know).

One year of development

After more than a year of development, the app was functional. There were team member changes along the way, and even a JavaScript developer had contributed to the app.

The app had gone through a couple of UX changes, and will probably go through a few more. To be released to production, this app required approval from an external governing body. At the time of writing, the governing body has tested and approved the app for use. The adoption of the app is now progressing and will take quite a while as adoption slowly picks up.

Technical challenges

During both the POC and full-scale development, there were a couple of technical challenges that Fabulous had.

Text Input

The first and biggest challenge was the slow update-loop on Android while typing. Contributors did a fantastic job trying to fix this, but unfortunately, the fixes were never sufficient. To work around this, we add a ref to the text field in the model, and when navigating off the page, read the value from the text field. This change means that keystrokes are not sent through the update loop. The downside is that there is a variable (ref) in the model.

Slow UI

Moving on to the next challenge was the app running slow. After many months of development, the app was quite large. The primary model contained every top-level page in the app

type model = {
    pageOne: PageOneModel
    pageTwo: PageTwoModel
    pageThree: PageThreeModel
    pageFour: PageFourMode
    currentPage: PageOneModel

This idea seemed fine initially, but once there were many pages, with many states, app performance was an issue. The algorithm to calculate the difference for the new model was quite slow. On Android, it was too slow. The solution was to populate only the current page in the model and create each page on the fly. The result was a much faster-running app for both platforms. Finding the fix for this bug was not an easier task. With so much development, it was not clear precisely what was causing the app to run so slowly. The fix was the great work of one of the team members.

Cell Ref/dispatch function - skipping the update loop

There were a few other cases where things did not work when being passed through the update loop. During the POC, it was clear that animations were one of these cases. Another example was attempting to open a PDF from the app (via another app). It turned out we didn’t need animations. For PDF, by skipping the update loop and making the request directly in the dispatch function, everything worked.

Live Update

Getting the UI right for any mobile can be challenging. Doing this for two different OSes with one code base is even more challenging. For this reason, Live Update seemed very promising, and in the early days, it was! However, as the app increased in size, Live Update became slower. There was too much code to compile and send over the wire that it was easier to re-deploy the app. Additionally, there were more dependencies in the app, which became harder to manage/mock. We don’t use Live Update in the main app anymore.

All is not lost with Live Update, however. Instead, when we are designing a new screen, we create a new project. The developer can then use Live Update on the new project. The speed of updates is fast, as there is little code to compile. Also, there are no dependencies, as well. Once the UI code is all set, we copy the code into the main app. A quick sanity check and a few touches result in a pretty good workflow. This workflow allowed a JavaScript developer to contribute to the project, building out a few UI pages.

Customer Renderers

One concern that I had during the POC was using custom renderers. Custom Renders are not very easy to use in Fabulous. This concern was unfounded, however. Building out most of the UX was natural, given the flexibility of the Fabulous UI DSL. The use of controls is quite different from that of XAML. Instead of trying to reuse controls and override the behavior, it is easier to create a new control with the basic controls from Xamarin Forms. Given this project did not have any extreme UI requirements, there was no need for custom renderers.


For this project, Fabulous worked out well. We didn’t have any loss in productivity fixing typos between code and XAML. We had very few NullReference exceptions during the project. Generally, productivity was quite high. We lost some productivity with the learnings above. Developers should expect some challenges when adopting new technology.

This project (both the app and backend) had contributions from developers whose primary programming language was another mainstream language (C#, JavaScript, Java). These contributions demonstrated that F# is a simple programming language to learn. With some training, each developer was able to add code to the project.

Unfortunately, not all developers saw the benefit of the change. The common criticisms were: tooling was lacking or too slow (Mac/Linux) F# was only a syntax change, so why bother learning Improving the language and perception in these areas would help grow adoption.

For reasons outside of the team’s control, it is unlikely that future projects will use Fabulous (or even Xamarin).

This post is licensed under CC BY 4.0 by the author.