Levels of Abstraction For Frontend Frameworks
What technology should you use to build your frontend (which includes mobile)? There isn’t one right answer. There are different frameworks at different levels of abstraction. Let me walk you through them so that you can pick the right level for your needs.
Low-Code
Low-code frameworks are the highest level of abstraction [0]. You get to the outcome the fastest. The barrier to entry is the lowest, so a semi-technical person like a PM, designer or marketer can build a minimal product by himself. Or even a series of such prototypes to see which one has potential before focusing on that. This person can be a sole founder. Or a person who wants to quit his job to start a startup can build a product on the side, validate it, and only then quit his job. Or a person in a company who has an idea can build a proof of concept to show to other stakeholders, validate with users, and get buy-in before it’s implemented “properly” using whatever stack the company uses, like Django. Or the marketing team can build a side project in a week whose primary purpose is to have more users hear of and use the company’s primary product, like the ClearTax tax calculator. My financial advisor used a low-code tool to build a retirement calculator.
Low-code frameworks have a ton of uses. This is a specific example of a general principle that when the barrier to doing something reduces, tons of use cases become viable that weren’t previously [1].
Unfortunately, low-code apps are not portable. You create an app using a certain service, and it runs on that service. One tool we considered using even charges per user, not per developer, resulting in an annual bill of thousands of dollars for our startup of 20-something people, which we did not even waste time evaluating.
Whether low-code tools support a polished user experience for a user-facing, as opposed to just an internal, app needs to be figured out.
Progressive Web App
Say low-code doesn’t work for you, because of UX, pricing, lock-in or because you want to use open-source and thus be in control of your stack. In that case, the next lower level of abstraction from low code is a PWA, which lets you support web and desktop with one codebase.
A PWA is the right choice only if you need to support web users. This can also be mobile web. For example, if you’re a service that users use infrequently, like car breakdown, many users won’t install your app. When their car does break down, they might use their mobile browser to use your service. So a PWA is worth considering if you need to support web, either desktop or mobile web.
With a PWA, you can iterate fast without bottlenecked by app store review. If you have a serious bug, you can roll back immediately, not after multiple days. You don’t have to contort your product or business model to fit Apple and Google’s demands. New features are more likely to launch simultaneously across all platforms, preventing user confusion from a feature not available on mobile. The UX will be more consistent between platforms, as opposed to (say) a feature being called something else on mobile, which happens naturally if you have two codebases.
Which framework should you use to build a PWA? I suggest Vue.js [2].
If you need to be in the app stores for discoverability, you can use a wrapper for that. You’ll still be able to make changes without going through app review, since the code loads from the server rather than being included in the binary. The binary is just a shell.
If you need some native capabilities, you can enable those in the app store version of your app, and degrade when accessed directly via the browser.
iOS doesn’t support PWAs, so on that platform you’d degrade to a responsive web app.
Hybrid App In Flutter
If low-code and PWAs are too high-level for you, the next lower level of abstraction is a Flutter app [3]. It won’t work via the web, whether desktop or mobile web, but in exchange you get a better UX than a PWA.
This makes sense for a mobile-only product. Or for a product that supports both mobile and web but needs a better UX than a PWA can provide.
Mobile Apps In Swift and Java
You get the best quality by building separate native apps for iOS in Swift and Android in Java.
Hybrid app frameworks like Flutter or React Native take you from 0 to 90. Pure native apps built in Swift or Java/Kotlin take you from 90 to 100. If you’re not already at 90, it’s premature optimisation to choose pure native apps. For most startups, reaching product-market fit, understanding users, building something users want, breaking even, etc are the immediate problems. If you don’t solve these quickly, you’ll go bust, and nothing else will matter.
And going from 90 to 100 costs a lot more. This is no different from any other market where, as performance increases, cost increases even faster. If you want to buy a car that can reach 300km/hr, it doesn’t cost twice as much as one that can reach 150km/hr; it costs ten times as much.
There are a few exceptions where pure native apps are called for:
You work closely with the hardware, like Futurecam does. Or you require the maximum performance, like doing machine learning on the edge.
You don’t mind spending hundreds of thousands of dollars a year staffing up an iOS team, and hundreds of thousands of dollars more staffing up an Android team, instead of just one.
You have 100 million users.
Getting the last bit of responsiveness and UX fidelity is more important than the speed of iteration, for a product that has already scaled and stabilised, like Gmail.
In summary, choose the right level of abstraction for your needs.
If you’re interested in the backend, read Levels of Abstraction For Backend Frameworks.
[0] Which is funny when you consider the name.
[1] For example, when the Internet made it possible for everyone to broadcast their thoughts to the world, without having to get a job at a magazine, blogs became possible.
[2] Why Vue? It has less complexity than React and especially Angular. Vue was designed by an engineer who worked on Angular and took just the good bits from Angular to create Vue. Vue is therefore more productive to work in, for small teams, and to build MVPs quickly. On the other hand, Angular and React were designed for Google’s and Facebook’s scale, respectively. Unless you have dozens of frontend engineers on your team, don’t cargo cult Google.
Vue is also incrementally adoptable — you can use whatever parts of it you need to. It’s not all-or-nothing. When using Vue, you don’t have to learn a non-standard way like JSX to do what HTML, CSS and Javascript already do. The resulting code will be understandable to engineers who don’t know Vue, and in the process you’ll build up skills that will be more broadly useful.
The downside to Vue is fewer engineers available who know it, but that’s offset by its ease of learning. It’s worth learning an unfamiliar framework if it’s quicker to learn than other frameworks and makes you productive.
[3] Why Flutter instead of React Native?
69% of Flutter developers would use it again, while only 58% of React Native developers.
One major startup moved from (among other technologies) React Native to Flutter. So did another early-stage startup I was advising; the founder said that Flutter is more solid structurally and faster to develop for.
I read that with React Native, half the time you’re amazed at how productive it is, while the remaining half the time, you’re fighting with the framework. Facebook doesn’t care about bugs that don’t affect them, and have even locked a bug on the bug tracker where too many people were requesting a fix. That’s not a responsible attitude from the maintainer of important infrastructure that you depend on.
Flutter has better documentation. It also has more built-in widgets.
Flutter’s performance is likely to be better, since it uses a statically typed language (Dart) and compiles ahead of time to binary. React Native also has to go through a bridge between native and Javascript, which adds latency.
React Native has some advantages as well:
If you also use React, you can share knowledge and some code.
You use Javascript rather than having to learn a custom language like Dart.
React Native has more APIs that work with the hardware, and over time, more building blocks like SQLite that are available to native apps are being plumbed through to React Native.
In my opinion, the advantages of React Native don’t outweigh its problems, so I’ll recommend Flutter.