Hello, my name is George Herbert and I am a lead developer currently working as part of the HMRC Mobile App team. HMRC is the UK’s tax, payments, and customs authority. The app helps users to access their Help to Save accounts, manage their tax credits, and review their personal tax situation among other features. The team comprises iOS, Android, and backend developers. We encourage all developers to try other disciplines within the team, which gives us a reasonable level of cross-skilling. My role within the team is being the lead developer of the backend microservices.
About the HMRC App
The HMRC app has been in existence since 2012 and started off as a simple tax calculator. During 2016 the team undertook a rebuild by refining existing functionality, as well as adding the ability for users to login and manage their personal tax affairs, such as their Help to Save account or their tax credits. This means they do not have to ring HMRC or fill in any forms. Currently, we have half a million users a month, with users returning on average 7 times a month. The app is aimed at personal tax users and, when compared to the equivalent web services, it accounts for 50% of total traffic in the personal tax space. One of the app’s most popular and long-standing features is the tax calculator. The calculation logic for this is shared with the web. The web and the mobile calculator combine for 5.7 million visits a year of which the mobile accounts for 2 million of those.
From a Kotlin perspective, the Android team has been working gradually to migrate the app. At the time of writing, 86% of the app is now written in Kotlin
Use of Kotlin Multiplatform
Around 18 months ago my Tech Lead called a meeting to discuss the use of Kotlin Multiplatform (KMP), among other technologies, to help simplify and consolidate business logic within the apps and service. It was agreed that the HMRC Mobile App team, in partnership with Capgemini, would investigate this open-source product as a possibility within the app by starting simple and then going from there.
We wanted the user interface (UI) to be native as this was already built. We also felt building a core for business logic that could be shared, regardless of the choice of UI, would allow us to share this with the web more easily.
As mentioned, one of the main features in the app is the ability to calculate an estimate of your tax and take-home pay based on your salary, payment frequency and tax code. Updating the calculator every year required days of manual testing to ensure that everything worked as expected and had to be done for every platform! We identified this as an area that really needed an overhaul, to help with maintainability adding new tax bands each new tax year and reduce testing effort. The challenge was anything new still needed to support iOS, Android & web.
I am not an Android developer or even a Kotlin developer, my background is a Scala developer. I was keen to learn Kotlin and this seemed like a good opportunity. Within a couple of weeks, the tax-kalculator (see what we did there) was born: a Kotlin multiplatform library, with coverage of 98% and ready for use in the Android and iOS, and even the web version of the tax calculator. Adding new tax years now takes less than an hour and very minimal manual testing, thus saving us days of effort and time.
Over time, we have started to add other multiplatform aspects to the app such as a Help to Save calculator that will help forecast the amount of money you can save as part of the scheme. Going forward we are looking into more sophisticated uses for KMP that would help reduce duplication and improve the user experience across the platforms.
Getting to grips with KMP
As we began using KMP there were a few challenges we worked through as a team. The first was around setting the Gradle to support the platforms, as every example we looked at was slightly different and we were using Gradle.kts which was even more sparse when looking at an example. The issues around limited documentation, or outdated examples, is becomes less of a challenge as the popularity of KMP increases. Furthermore, as part of 1.4.0 the Gradle config has been simplified with the hierarchical project structure making this much easier and straight forward.
We faced a challenge with getting the framework for iOS in a state that could be consumed in our app without directly linking them in the Xcode build. One of the team’s iOS developers found a shell script that we added to our CI, that creates this and exports it to our GitHub. An example of this shell is on the repository for the project called package-ios.sh.
Finally, the iOS team faced the challenge of using multiple KMP projects in the same iOS app. This since been resolved in a newer version of KMP. As for the latter we temporarily (until the fix for this was added in 1.3.70) put all the KMP projects in one “super” library that contained all or KMP functionality just for iOS.
My advice is that if you want to try out KMP start small. For example, just write some business logic which is pure Kotlin and does not need platform-specific implementations, all the code should be in the commonMain. This makes the initial getting to grips with KMP simple as you don’t need to work with the actual and expects keywords. Once you are happy with the projects and their structures etc and they are working in your respective apps look to spread your wings into more challenging KMP (like consolidating your network logic and error handling for example).
I hope this has been interesting. If you have any questions about using KMP or either of our projects that are linked below, please feel free to message me on Twitter (@georgeherby).
HMRC KMP Libraries
Help to Save Kalculator
Something extra whilst your are here…
Recently the HMRC App team has open sourced its UI components for Android and iOS allowing anyone to build accessible apps with the same look and feel as the GOV.UK Design System.