Recently, Karlo Karagic, one of our Senior Android Developers, had a chance to attend a “SuperMinds: Mind the App” conference where one of the talks piqued his interest, which we will expand on later. Let us give a little summary of all 4 talks there, first.
Eliza Camber opened the talks with “Machine Learning on Android”. This was an overview of the current state of ML (Machine Learning) tools in the Android world with a few examples of pre-trained models Google provides - bar code scanner, optical character recognition, speech-to-text, etc.
Next up were Luka Leopoldović & Filip Debelić with “Past, Present and Future (of a product app)”. This was a developer-focused talk with an emphasis on Android tools and architecture. They showcased their multimodule app, which was made with team scaling in mind.
After them on stage came Christina Lee with a more psychology-themed talk: “The Dog and the Tech Lead: What Animal Training Taught Me About Being a Better Mentor.” This was a fascinating talk on soft skills in the industry. The presentation was on how positivity and setting up someone to succeed have substantial positive effects on the learning process.
Finally, the focal point of this article. The talk by Garrick Toubassi. His topic was “Shipping mobile apps in start-ups and big tech”. The talk was structured around three examples (two startups and one enterprise app).
The app we are talking about here is Inbox by the Gmail team. It was one of the first apps that tried to make a uniform experience on two mobile platforms and on the web. This meant writing the code three times, which is not a great idea (like the author said - “I don’t trust the developer to write it once, let alone three times”). They eventually found a way to write 60% of the app in Java (the UI for android and business logic for all three platforms) with J2CL (Java to JS) and J2OBJC (Java to Objective-C). From this they had a couple of conclusions:
Since then, we have come a long way, and now we have more than just hacks to make cross-platform work. One of the tools is Kotlin Multiplatform Mobile. Even though it’s in an incredibly early stage of development (when we tried it, we discovered many quirks that made life much harder than it needed to be). Nevertheless, enterprises, such as Philips, Netflix, and others, are already giving it a shot in production, as the framework has lots of potential.
But two absolute kings in this domain are Flutter and React Native. As opposed to KMM (Kotlin Multiplatform Mobile) they also handle the UI layer, and you can write whole apps in their respective languages. Together they cover 80% of multiplatform frameworks market. As a side note, Flutter surpassed React Native’s popularity in 2022.
Two examples here: Shopstyle and Locket. The former is an aggregator for the fashion industry, while the latter is a photo-sharing widget. Conclusions that came from analyzing them were overly similar, and as such we will combine the findings. The conclusions were:
Biggest takeaway here is it is not that important with what you write your potential million-dollar app. For example, the rusty LAMP (Linux, Apache, MySQL and PHP) stack is still (fairly) popular nowadays. On the other hand, it is also completely viable to write the application in innovative frameworks as well (hopefully not over the edge – technology should at least be in the beta stages of development, Qwik comes to mind).
The only advice we would offer here is to stick with something close to home. Like the example given, if you are a JavaScript or a React developer, why not make your mobile app in React Native. There will be challenges, but at least you will not be fighting the language and the platform.
I completely agree with Mr. Toubassi here. Premature optimization and overengineering solutions are all too common in software development, even if it can be detrimental to the app's time to market and long-term success. The issue here is that you don’t know what the bottleneck will be in two years' time. We shouldn’t get too attached to the code any way, as when we are done, we will have the knowledge and insight to make it even better. This will never change.
Of course, this doesn’t mean we should get back to writing all our code in one file and calling it done. There is a sweet spot in the middle. In the Android world, we really like sticking to predefined architecture, considering our platform of choice is hard to develop for. As such, we have learned, over time, to move our code as far as possible from Android-specific code. This allows us to have nice layering in the codebase, which enables us to switch/change parts we don’t like or that need improving (and protect us from changes in Android OS itself). This is one piece of the puzzle: make our code as clean as possible.
The second part is when your app gets traction and your team and build times get colossal. Now we are in the domain of modules, build scripts and integrating app development with other processes in your company. How do you optimize this part? Well, it's hard, and requires close cooperation from everybody in the organization. Each company is but a group of people, and people are complicated and not always predictable, especially the more there are.
The next stage comes when you get from the startup to a large corporate level app. Now you have even more people, and you start having custom-made tools to help you with your processes.
Let’s not forget about your millions of users. Let's look at an example: at Google, every problem is a problem at scale. Think of a one in a million bug that can happen; a bug that is highly unlikely to occur. For most of us, developers, it's not an issue, but for a Gmail app (just an example) that’s a critical issue potentially affecting thousands of people. How to prepare for this? How to ensure you detect, and get rid of, bugs most others could just ignore?
I could go on, but I think this made my point clear. We should prepare for the future, but still not overthink it. There are too many variables hidden in time, and it is a fool's errand to try and predict the future.
Getting up and running fast, is the key, just with some reservations to always keep at the back of the head. The example of Twitter running on a Ruby on Rails is a great one. They got it up and running and got millions of users. Everything was fine, until... it wasn’t. One abandoned internet icon is the famous “Fail Whale”. It showed up every time Twitter’s backend would not be able to handle as many concurrent users as they had. It happened often. So often, that users would feel nostalgia once they stopped seeing it or even felt out of place.
That’s one of the cons of assuming that “we mostly think about what’s now, and what’s later is later.” Ruby is a slow language. A painfully slow language; always was, always will be. By running a RoR backend, you know eventually you will have to rewrite your app from scratch.
When writing the MVP, you must have scalability at least in the back of your head. There are full-stack frameworks, with a rich ecosystem of plugins, that are much more future-proof than Ruby’s Rails. There is Node’s Nest or Fastify, Kotlin’s Ktor, or even Go’s Fiber.
Lastly, cross-platform mobile app development is not ideal in terms of quality of resulting apps. It’s not supposed to be. It’s supposed to be a solution to a different problem. Furthermore, it solves the problem of writing the same app two or three times (and not the problem of subpar developer experience); it reduces the development time.