As a web developer, I believe in the Web as a development platform. In fact, it’s my (and many other’s) go-to platform for creating amazing apps easily and quickly.
However, I do acknowledge the advantages of native development - especially from the user perspective. More advanced functionalities, better performance and compatibility with the underlying platform - there’s certainly much to appreciate in native apps.
So the question is - when to choose which route? Now, as a web developer, I know my opinion might be a bit skewed, but I’ll try to do my best.
Usually, native apps are better in scenarios where web apps are worse, so we’ll start with the Web’s pros and cons while comparing it to native on the side.
Let’s get started!
Pros and cons of the Web
However, the Web is not all sunshine and rainbows, and pretty much for each of its pros, you can find a con. To give you some examples:
- the vibrant ecosystem also means that it’s easy to get left behind, or acquire technical debt
- even though the Web is “cross-platform,” you still have to commit additional development time to deal with responsivity, cross-browser incompatibilities, and backward support
- lastly, though the core web technologies might be easy to get started with, they all have some quirks when you look deeper, and if not that, their simplicity and lower-than-native performance might be limiting you from realizing more complex projects
Why (not) go native?
With these cons in mind, it’s easy to see how for each one of them, going native could be the answer (even if it might be far-reaching in some cases).
Going native means better integration with the platform you’re running on, better performance, access to features and possibilities you won’t get on the Web, and in some cases - less friction with adapting to different devices and form-factors since you’re operating on a limited set.
In a perfect world, either all apps would be native, or the Web would have all the native features.
Currently, even though the first option would be technically easier to achieve, I’d say it’s the second option that we see unfolding.
The Web and underlying technologies are constantly being improved, performance catches up to native, and new, native-like features are being added. On top of that, new projects, teams, and start-ups, more often than ever before, pick the Web as their first frontier, and it’s easy to see why.
Unless your project is directed towards a single platform or depends on a native-only feature, there’s no reason why you shouldn’t at least try going web. The bigger potential audience and faster development coupled with less knowledge required are just too big advantages to be ignored.
Everything in between
So, with this overview of the Web and general native platforms, it would seem like the decision between going native, or web should be as easy as choosing between black and white. However, like with all things in life, there are always some shades of gray in between.
In the case of development platforms, those “shades of gray” can be interpreted as “development targets” - intermediaries sitting between you and the development platform(s), allowing you to easier develop for them.
I’m talking about things such as:
- Electron - for building desktop apps with web technologies (essentially a Chromium browser packed into a separate app)
- Cordova / Capacitor - for building mobile apps with web technologies (a WebView packed into a separate app, like Electron but for mobile)
- React Native / NativeScript - for building native mobile apps with web technologies (deeper native bindings, without the use of WebView)
- Flutter - dedicated toolkit for building cross-platform native mobile apps, recently expanded to the web and desktop apps.
- PWA (Progressive Web Apps) - a set of web technologies to make standard websites behave and perform more like native apps
- WASM (WebAssembly) - efficient format, a compilation target for different programming languages, capable of running in the browser and other environments, with great performance
- Browser extensions - extensions for browsers, build with web technologies, having access to more functionalities than websites.
With such an extensive list that’s far from covering all the available options, you can clearly see that the choice of your development target becomes much more complicated.
To form a decent decision-making recommendation, let’s start with the upper-most choice between pure native, pure web, or a development target.
I’d say this is always a question of resources, knowledge, timing, and your project’s feature set. But to summarize it the best I can:
- If you want to deploy quickly, access boatloads of users, and save resources and time along the way - go with the Web whenever possible.
- If you want to integrate deeply with a specific platform, use specific native-only functionalities, or perform very intensive operations - native is the way to go.
- Lastly, if want to access all the users, providing the best experience possible for every one of them - pick one of the development targets or, if you have a lot of resources and time, build all the web and native apps required individually.
The choice between development targets is more interesting than just “native or web,” and I think this is the question to be asked in 2021.
PWA and WASM
Picking from the options I’ve listed, let’s start with WASM and PWA, as I think these 2 technologies go pretty well with each other.
If you’re already familiar with the Web platform, implementing PWA support or utilizing WASM will lead you to better performance and user experience.
PWA is arguably the quickest way for most gains if you already have a web app running. It won’t improve your app’s performance, but with features like app installs, notifications, and background scripts, it can boost your web app’s feel closer to the native level.
On the other hand, WASM requires a bit more learning, but with tools like AssemblyScript and some knowledge of TypeScript (check out my article on that), you won’t have to go far from the Web to enjoy WASM’s benefits. It can be useful in heavy-compute applications like games, data manipulation, math, physics, etc. You can already see it in action in popular apps like Figma, or Avocode, providing native-desktop-level experiences on the Web.
Capacitor and Electron
Going from here, you should look into tools such as Capacitor and Electron. These can further your web app’s native feel and give you access to many native-level features.
Now, although they’ll both have different features and APIs, they’ll still allow you to keep a single core codebase. This will lead to the most efficient solution for seemlessly targeting all major platforms.
Things get a bit more interesting when we take a step back and take a look at Capacitor and Electron from the starting point - “no web app whatsoever” - perspective. Then, they become arguably less appealing.
Sure, if you know the web technologies well, both Capacitor and Electron will allow you to build advanced native-feeling apps with native-like features, but that’s something you can increasingly do with the Web and PWAs alone. These technologies won’t give you any performance improvements (unless coupled with WASM or native Node modules on Electron), and their biggest advantage is arguably having more control over the platform you’re running on (like access to a truly persistent file system)
So, before going with Capacitor or Electron for your next project, take a step back and deeply consider if you couldn’t make your app run on pure Web. If no - go for it, but if yes, then try starting with a web app, (if necessary replacing file system access and heavy computing with the cloud), and then take a look at Capacitor or Electron, depending on your needs.
React Native and NativeScript
Moving a bit further from the Web into the native side, we stumble upon technologies such as React Native or NativeScript. The idea behind both is the same - allowing developers to create truly native mobile apps with (seemingly) web technologies.
The problem with them is that they’re placed in a somewhat gray area. They’re neither truly native nor truly web. This creates a problem, as you become limited to the specific set of functionalities the toolkit supports or have already been “ported” by the community. You don’t have access to most of the web dev ecosystem unless it’s pure JS, not touching HTML or CSS, and integrating custom native functionalities, will require additional time, effort, and knowledge.
So, you essentially have tools meant to give you better, close-to-native performance but work best with only simple apps that arguably don’t require that.
Don’t get me wrong - there’s still some usefulness to these tools. If you’re primarily profound in web technologies, but also have some native knowledge, React Native or NativeScript might be just for you. You only need to know their advantages and limitations while also not being scared of getting dirty with some native code.
In return, you’ll get arguably better development experience, a single codebase to target both platforms, and better performance than if you were to use Capacitor.
Nowadays, you can’t really talk about cross-platform development without mentioning Flutter.
This Google-originated native app toolkit has been sky-rocketing in popularity lately, and for a good reason. Build from the ground up for cross-platform native mobile app development, Flutter focuses heavily on development experience, rich functionalities, and great performance.
Even though Flutter started as a cross-platform mobile native app toolkit, it expanded to the Web and is now on its way (testing stages) to conquer desktop.
It still shares some of React Native’s and NativeScript’s drawbacks, like having to sometimes dive into the native code but also learn another programming language (Dart). However, with its popularity, bigger community, more functionalities, and a wider range of supported platforms, it’s easy to see the appeal.
With that said, I wouldn’t recommend using Flutter just to create a website, to later port it to native mobile or (in the future) desktop app. Also, don’t bet on Flutter “killing” or replacing Electron’s top spot on the desktop side any time soon.
Use Flutter for what it’s already good and tested at - cross-platform mobile apps. Only when you feel it’s the right choice, try reusing the same Flutter codebase on the Web. Keep in mind you’ll still have to learn Dart, the vast Flutter toolkit, and have some basic understanding of native platforms you’re targetting.
Last but not least, we’ve got browser extensions, which are completely in a category of their own. If you want to create a browser extension, then you most likely know exactly what you want.
Browser extensions serve as a unique kind of platform. You can create special experiences that slightly extend beyond the Web’s capabilities and allow you to interact with the user’s browser, store truly persistent data user-side, and access data from websites the user visits.
However, you have to know that all these functionalities are kept behind a wall of user permissions and (at least on Chromium browsers) require you to go through verification process to get listed on the store. That’s good user and security-wise, but it can feel limiting if you’re primarily used to the freedom of the Web platform.
I’ve only recently got into browser extension development and have been enjoying it so far. I’ve even created my first product on this platform - CodeWrite - a blogging tool for developers.
It’s actually a PWA - browser extension hybrid, in which browser extension connects with PWA for it to be both “installable”, as well as have truly persistent storage for local blog posts storage (resistible to history and cache cleaning), and access blogging websites like Dev.to, Hashnode, and Medium, to auto-fill your articles in their respective editors, and handle all the incompatibilities inside the extension pop-up (like converting code snippets to GitHub Gists, resizing images, changing formatting, etc.) Check it out if you’re interested!
So, there you have it. Ultimately, as always, the choice comes down to you (or your management), but I hope that I’ve at least helped you somehow in making it or just let you know of the available options.
What’s your platform of choice? Is it the Web, some kind of a native platform, or maybe browser extension? Depending on your choice, what’s your “development target”? Did you try tools like Flutter, React Native, or Electron? Let me know your thoughts and choices in the comments below.