Building a modern application is a complex business. You can build a native phone app, but sadly if you do this, you will usually have to code two versions of it, one for iOS and one for Android. There are cross platform app development toolkits, which allow you to use one codebase for both of platforms, but then you’ve got another problem, what about the web?
In the worst case scenario you make three different versions of your application’s front end codebase. For some digital properties this makes sense. They want and can afford to engineer the very best native experience on each platform, so they invest the extra time and effort.
For a startup however, this is a nearly impossible proposition. When I started QuirkLocal I knew I couldn’t afford to have two, let alone three versions of the codebase, but I also knew I eventually wanted to support iOS and Android with a version of the app.
I started off targeting the web by developing a Progressive Web App (PWA). PWAs are typically web applications that have some additional features and meta data to make them installable on both desktop and mobile platforms. A key feature of PWAs is that they should be responsive, that is, their layout should shift to accommodate the size of the display device – different layouts for mobile, tablet and desktop usage.
Developing a PWA adds a bit of complexity to your application, making it responsive can be a tricky task as well, it’s hard to get right. For QuirkLocal we picked a ‘mobile first’ approach, preferring the mobile layout, but added some extra features to take up the space available on tablets and desktops. We’ve got room to improve this in the future, but for now, it works well on all devices.
We chose the Ionic framework for our app. It supports responsive applications out of the box, and has a wealth of mobile friendly UI elements that support native look and feel when loaded on mobile devices. This makes our QuirkLocal look great on the web for desktop browsers and in mobile browsers on iOS and Android.
But what if we want to go beyond the web and deliver an installable mobile app? As a PWA our app is installable, but the process is clunky, and not well supported on iOS. I am not sure anybody’s ever installed our app on a mobile home screen other than in testing. What we need is a real mobile app available in the app store.
Ionic has an answer for this as well. It comes bundled with the ‘Capacitor’ framework, which is descended from Apache Cordova. Both are from a class of frameworks that bundle up web applications into installable mobile apps, using the mobile platform’s native web browser.
Basically they create a tiny little native app wrapper around your web based code, and then launch that code in a web browser. On iOS it uses mobile Safari, and on Android of course it uses Chrome. The result is typically called a ‘hybrid’ app.
We use this to create both of the mobile apps for QuirkLocal from the exact same codebase used for the web application. It’s very cool. But there are a couple wrinkles.
The application wrapper uses a web browser to display your application code, but it doesn’t behave exactly like a real web browser. Your web pages are loaded locally, so interacting with a remote backend gets complicated because of the way web browsers secure content.
Usually a web browser will let your web code interact with services provided from the same domain the web code was loaded from – this is called the ‘same origin’ policy. At oakpark.quirklocal.com for example, both the web code and the backend services run on the same domain. But when you load a Capacitor wrapper app on iOS or Android, the web code is loaded from a local domain, and by default cannot access the backend services on an internet domain.
Because of this, Capacitor provides Javascript wrappers for native platform web requests. Your code can detect when you are running as a mobile app, and not use browser requests (which will fail) but instead use native web requests, which can query any internet domain without limit.
Capacitor also has wrappers for sharing functionality. If you want to share a link from your app you can engage the native sharing dialogues. There are wrappers for other native dialogues and alerts, the camera, geolocation, clipboard access, and push notifications, to name a few. All of these integrations allow your web app to provide a more native experience when run as a mobile application.
As a result, our three versions of QuirkLocal don’t quite run exactly the same code. Small portions of the app detect where they are running, and sometimes opt for a native integration when it improves the user experience. But approximately 99% of the frontend code is identical between all of the versions. This means most of the changes we make get coded once, and work transparently on all of our targeted platforms. That’s a huge advantage.
Are there any downsides to hybrid apps? Sometimes people complain that web applications don’t look ‘native’ enough on mobile platforms. Ionic’s user interface toolkit can help with this, but in general I am not sure most users have strong expectations around native look and feel on their respective platforms.
There are some who claim web apps are just too slow and clunky, but that’s not been our experience with Ionic and Capacitor. The apps are snappy and fast on all target devices. I think this is likely more a function of application design. A slow web app will be slow everywhere. We’ve designed ours to be fast and responsive everywhere it runs.
Ionic/Capacitor aren’t the only way to accomplish this same goal. There are many, many mobile friendly web toolkits out there, and for mobile app packaging Apache Cordova is a free and open source alternative. Our approach of course won’t be the best for every company, but it’s been economical and effective for QuirkLocal.