Field note / experiments
ANativeAppShouldBeaURL
What if native apps opened like webpages: no installation, no update ceremony, just a URL? I built a prototype to prove that the hard part is no longer the technology.
An EV charger has one job: sell electricity.
Yet using one often begins with scanning a QR code, finding an app, installing it, opening it, creating an account, and perhaps downloading an update before the machine will accept payment. Six months later, the app is still taking up space, waiting patiently for the next visit to that particular brand of car park.
Nobody approaches a charger hoping to begin a long-term relationship with its software. The job is to buy electricity and leave.
The alternative is almost boring. The QR code could simply open the application. Not a website pretending to be an app, but the actual native interface: platform controls, proper navigation, and access to the payment APIs already on the phone. It could ask permission to send a notification when charging is complete, keep the small amount of data needed to work offline, and disappear when it is no longer used. No installation ceremony. No application package permanently occupying space. No update standing between the driver and the electricity.
The app would be a URL.
We bundled the wrong things together
The browser is two inventions that happened to arrive in the same box.
The first is an extraordinary distribution system. Send someone a URL and they can use your software. Code arrives as it is needed, updates appear on the next visit, and applications are isolated by origin. There is no separate installation and no moment where the user has to decide whether this interaction deserves permanent residence on their device.
The second is a user-interface system built from HTML, the DOM, and CSS. Those are remarkably capable technologies, but they grew out of documents. We have spent decades teaching them to behave like applications.
Native apps have the opposite arrangement. They get the controls, interactions, accessibility, and platform conventions for free. In exchange, each application becomes a package that must be discovered, reviewed, downloaded, installed, updated, and eventually cleaned up.
We talk about these as two choices: build a website or build a native app. But the choices inside them are not inherently connected. Web distribution does not require a web interface, just as native controls do not require a separately installed application.
I have tried the obvious alternative
I learned this distinction at my first full-time engineering job, although it took me a while to understand what I had learned.
I inherited an iOS app built with MonoTouch, later Xamarin, and immediately did what any sufficiently confident junior developer given ownership of a domain would do: I deleted it.
Two months later, the replacement was in the App Store. Its first three reviews were all five stars. I remember seeing them arrive and thinking I had actually done it. Apparently software engineering was much easier than everyone had made it sound.
Then the one-star reviews arrived. The app crashed, MonoTouch had rough edges, and making a stable mobile application was not trivial for one junior learning in production. It took about a month to stabilize. Eventually the good reviews returned, and the app became quite well liked.
Later, Google began penalizing sites without a mobile version, so we built one. Once most of the interface existed on the web, replacing the native app seemed obvious. Web development was faster. More people could contribute. We could ship without fighting the App Store for every release. The resulting Cordova app had more features and a full team behind it instead of one junior with dangerous levels of confidence.
Users liked it less.
We put much more effort into the web version and never managed to reproduce the experience of the native one. This was around the time the industry was confidently announcing that HTML5 was ready. Our users, inconsiderately, had not read the announcement.
The lesson was not that web applications cannot be good. They clearly can. It was that the best part of the web was never the imitation of native controls. It was the link.
Put the pieces in a different order
I built Unbundled to test what happens when we keep the link and replace the interface.
It is a small experimental runtime built around React Native. Give it a URL and it can download an application from that origin, run it with native UI, isolate its storage and permissions, and fetch additional parts only when the application needs them. The application is not installed as its own package. The origin is its identity, just as it is on the web.
React Native is useful here precisely because it means there is little to invent. It already turns JavaScript into native interfaces across platforms. JavaScript runtimes already execute downloaded code. Browsers already give us origins, caching, sandboxing, permissions, links, and incremental delivery. Operating systems already provide native controls, notifications, background work, and storage.
Unbundled does not solve every part of this. Its security boundary is not hardened for hostile code, and the prototype does not implement service workers, background execution, or push notifications. Those are serious pieces of production engineering.
But they are not unknown science. We have built all of them before.
The experiment proves the narrower point I care about: a native application can be delivered from a URL, use ordinary native UI, and keep the web's origin-based identity without every application becoming its own installed binary. This is mostly an integration problem. The wheels already exist; we have just attached them to different vehicles.
I call the result a Progressive Native App: native software that can arrive like a webpage, download only what it needs, retain state when useful, work offline, and deepen its relationship with the device without demanding installation up front.
The difficult part is permission
The largest obstacle may not be technical.
A runtime like this changes the unit of software distribution. The store distributes one runtime; after that, origins provide the applications. That is rather less control than platform owners are accustomed to having.
Android is open enough that much of the model works today. The same deployed applications also run natively in the Unbundled prototypes for iOS and macOS. But iOS restricts the pieces needed to make the complete experience useful: handling arbitrary web links, remaining available in the background, and distributing downloaded application code through the App Store.
I cannot prove those restrictions were designed to prevent Progressive Native Apps. I can show that they prevent them, and that loosening them would weaken the store's position between developers and users.
This does not need to replace every installed application. Games, professional tools, and software with specialized native requirements can remain packages. The interesting target is the enormous tail of things we install for one small interaction: starting a charger, paying for parking, checking in for an appointment, following one delivery, receiving an occasional local alert, or configuring a device twice a year.
Those applications should be allowed to appear when needed, remember enough to remain useful, notify us when invited, and fade away when ignored. We already have the technology to build that ecosystem.
What we do not yet have is permission from every platform to use it.
A native app should be allowed to be just a URL.