How I think Web Apps Should be Installed

Example web app install flow using ambient badging

There’s currently a discussion at the W3C about how web apps should be installed from web browsers.

I won’t chronicle the whole twenty year long debate here, but suffice to say over the years browser vendors and OS makers have tried lots of different approaches.

The current solutions being considered for standardisation in the Web Applications Working Group are:

  • The beforeinstallprompt event – An event on the window object implemented in Chromium by Google (but not adopted elsewhere) which allows developers to intercept the browser’s own prompt to install the current app and provide their own UI
  • A navigator.install() method – An explicit API implemented in Chromium by Microsoft and Google which allows developers to request installation of their app at any time (there is also a related cross-origin proposal for installing other apps)
  • An <install> HTML element – A declarative solution (prototyped in Chromium) with a special button, whose content and presentation is controlled by the browser, which can be placed in a document to enable a user to install the current app

beforeinstallprompt

Pros:

  • It gives the browser control over when an app can be installed, which may reduce noise slightly
  • There is a trusted native browser user interface for installing apps

Cons:

  • Unpredictable and confusing for developers. It’s an odd (though not unprecedented) API design to listen to an event which is emitted before something occurs and intercept it and call a method on the event object. Implementations of this event have so far been very unpredictable, with browsers using different heuristics to decide when to show an install app prompt.
  • Likely to lead to nagging popups, banners or install buttons inside web apps trying to get users to install an app.

navigator.install()

Pros:

  • An explicit, predictable API that developers can use when they choose

Cons:

  • Likely to lead to annoying popups, banners or install buttons inside web apps trying to get users to install an app
  • The UI is left down to developers so will be inconsistent, and could potentially even compete with the browser’s own prompts

<install>

Pros:

  • Trusted native browser user interface for installing apps (though buried in web pages)

Cons:

  • Likely to litter the web with install buttons
  • Potentially problematic for some apps like games which use canvas or WebGL instead of the DOM

In my opinion all three of these proposed solutions risk littering the web with (at best) install buttons or (at worst) nagging popups and banners. The web is already plagued with interruptions like ads, paywalls and cookie consent banners and this would just add to the noise – further eroding the experience of web apps compared with native apps.

Another Way – Ambient Badging

In my opinion, the user interface for installing web apps should be trusted, consistent, easy to discover, but keep out of the way when it isn’t needed. It should feel equivalent to installing a native app (not a second class citizen), but also work to the unique strengths of the web rather than just imitating the model used by native app stores.

My view is that we already have a declarative solution for a web page to point to a web app that can be installed, and that’s a Web Application Manifest linked to using a manifest link relation in a link element:

<link rel="manifest" href="manifest.webmanifest">

I believe Samsung coined the term “ambient badging” around 2017, but similar ideas had come before and after it, like Opera’s similar features and my own pinned apps proposal for Firefox OS in 2014 and ambient badging proposal for Fenix in 2019.

The basic idea is that the browser provides a subtle but immediately visible indication that the current web page is part of a web app that can be installed. In my opinion the best ambient badge for a web app is the web app’s own icon, but it could be a generic install button that appears somewhere in the browser chrome. The key thing is that there’s a clear indicator that the app can be installed, which doesn’t get in the way but isn’t buried deep inside a menu somewhere.

I’ve quickly created some example wireframes below to illustrate how this could look in existing mobile and desktop web browsers. When a user navigates to a page which links to a web app manifest (and the page falls within the navigation scope of that manifest), the browser displays a badge in the browser chrome indicating that there is an app that can be installed. Browsers can decide the criteria that a manifest needs to meet in order to show this badge (e.g. a valid manifest with a start_url and at least one icon), but it should be documented, consistent and predictable. The badge could potentially replace the site info icon if one is usually displayed, in order to reduce clutter.

App install hint

The first few times a user navigates to a web page which links to a valid manifest it might be useful to show a hint which teaches the user about the feature (ideally displacing the viewport rather than obscuring it), so that they know where to find it. Note that the hint overlaps the URL bar so that it’s clear it is browser chrome and not content. Once the user has used the feature, or the prompt has displayed a certain number of times, or they have explicitly requested it not be shown again, the hint would no longer be displayed. The install app feature would then keep out of the way until it is needed (and could additionally be present inside an overflow menu for discoverability). Subtle animated cues could also help draw attention to the badge.

When the user clicks on the badge, they are presented with an app install dialog.

The app install dialog shows the name and icon of the app, and importantly the origin it is being installed from. Again note that the dialog overlaps the URL bar to show that it is browser chrome rather than content. In my opinion it’s important that the language used in this dialog matches the language used for installing native apps on that platform (i.e. “install” rather than “add to home” or “add shortcut”) so that it’s clear that this action is equivalent to installing a native app.

The app install dialog could be combined with other site information like a site info dialog if that helps to reduce clutter in the browser chrome.

Depending on the design of the particular operating system, once the user clicks the install button (and after any progress indicator has completed) they could either be navigated to a homescreen or app dock to show the new icon appearing, or the browser chrome could simply disappear as the manifest is applied to the browsing context to create an application context using the display mode specified in the manifest.

Installed app in standalone display mode

Once installed, web apps should ideally be treated as first class citizens on operating systems, appearing in lists of installed apps in app launchers and settings, and getting the same icon treatment as native apps.

Example Implementation

I’ve implemented the W3C Web Application Manifest specification a few times now, on Firefox OS and a prototype tablet, but most recently for the in-development Krellian OS smart building operating system.

Like Firefox OS, Krellian OS only runs web applications and the terminology used in the UI is to “pin” them. Pinning an app immediately transforms its browsing context into a standalone display mode and adds its icon to the app launcher.

Early screen capture of pinning an app on Krellian OS

Why only websites with manifests?

A change to the Editor’s Draft of the Web Application Manifest specification in February 2025 added a new informative definition of “installable web application” which includes the text “Any website is an installable web application.” This is to reflect a recent direction of browser vendors to treat all web pages the same whether they link to an app manifest or not. I don’t agree with this and think it’s actually inconsistent with the normative text of the specification, which says a web site can only become an “installed” web application if it links to a web application manifest.

Saying that any website is an installable web application also implies that all websites are web apps, which I don’t agree with. In my view, allowing any web page to be “installed” dilutes the concept of web apps and further erodes their perceived value and quality when compared with native apps. I think good web apps have certain important characteristics which differentiate them from websites, but as a minimum bar a website should need to self-declare as a web app by providing a web application manifest.

What about app stores?

Another feature that Microsoft in particular seem interested in is the installation of cross-origin or background documents. Both the navigator.install() and <install> solutions have been proposed as working cross-origin to install another web app, in addition to just the current web app. It appears Apple are not happy with that idea, but importantly the W3C TAG have also expressed concerns.

A key use case for this feature is to allow a website to act as an app store from which users can directly install web applications from other websites. Whilst this is something that we implemented back in the days of Firefox OS and the Firefox Marketplace, I’m not convinced it’s actually needed, or in fact in the interests of the web.

I personally think that rather than app stores, the web can benefit from web app directories with curated collections of apps including links that users can follow to immediately start using the app before deciding to install it through the native browser UI. I think this better leverages the unique strengths of the web, which are that web apps can be discovered and used immediately without needing to be installed, with installation being an optional additional step a user can take if they want to save the app to their device to use regularly.

The Caveat

I acknowledge that these ideas are not new, and they have been tried before. For this to become the de-facto solution for users to install web applications it requires all major browser vendors to be willing to surface web app installation much more visibly in their user interface. The solution is one of UI design using existing technologies, rather than prescribing a new API design in a specification. Unfortunately this is in conflict with bad incentives some browser makers have to bury web application installation deep inside an overflow menu.

In particular, I think it requires Apple to start seeing web apps as a complement to their curated proprietary app store, rather than a threat, and treat web apps as first class citizens on iOS and macOS. Otherwise I think we are doomed to a further degraded experience which makes the web suffer. I urge Apple to embrace Steve Jobs’ original vision of web apps being first class citizens on the iPhone.

I think browsers which visibly but subtly surface a trusted browser-native UI for installing web apps, which are treated as first class citizens on operating systems, would be the best outcome for the web.

My Vision of a Smart Building Operating System

I have a vision of a smart building operating system.

A whole building operating system, built on web technologies, which weaves together every sensor, actuator and human-computer interface in a building into a seamless user experience.

Smart Building OS User Interface

This vision builds on everything I’ve learnt from working on Webian, Firefox OS and Mozilla WebThings.

Rather than a single desktop or mobile computer, the OS is designed to operate over many different pieces of hardware spread throughout a building.

Hub, Terminals and Devices

Every terminal is a web client, every device has a URL and a hub acts as a central web server.

OS Architecture

Hub

The hub is a central computer for the building.

Hub

This central computer is inspired by the “ship computer” trope and similar ideas often portrayed in science fiction (e.g. the duotronic ship computer from Star Trek, Holly from Red Dwarf, HAL 9000 from 2001: A Space Odyssey, Eddy from The Hitchkiker’s Guide to the Galaxy, KITT from Knight Rider or The Great Machine from Forbidden Planet1).

It acts as a central hub for monitoring, controlling and automating a building. Think of it as a permanent electrical appliance, like a boiler or a fuse box, but for information rather than heat or electricity.

As a long term vision, imagine the hub hosting a semi-autonomous software agent with a conversational voice interface and an interactive 3D model of the building. As a starting point, a server for hosting 2D graphical web applications.

Hub Architecture

Fundamentally the hub is a web server which hosts web applications and stores user data. Each application is isolated inside its own sandboxed container which includes all of the dependencies the application needs and can be atomically updated. Both the host operating system and applications receive automatic over-the-air updates. A reverse proxy sits in front of all the applications and routes HTTP requests to the correct application.

Hub UI

The first of those applications, the “killer app” and default home page of the OS, provides a unified web interface for monitoring, controlling and automating all of the connected devices in the building. It does this by bridging a range of different smart home protocols and commercial building management systems to a single standardised Web of Things API using the Web Thing Protocol, which is then consumed by the web front end. Third party apps and services can also request access to this API.

Terminals

Terminal

“A computer terminal is an interface where the mind and body can connect with the universe and move bits of it about.” — Douglas Adams, Mostly Harmless

Terminals could be a smart display or smart TV (think tabs, pads and boards), or even a smart speaker or VR headset. These are devices which provide a human-computer interface through vision, audio or touch.

Terminals act as web user agents which enable users to interact with the web applications hosted on the hub, but also discover and use installable web applications from anywhere on the World Wide Web.

Terminal Architecture

On the front end is a shell for discovering and using web applications. On the back end are core services which provide the shell with access to hardware such as network adapters, displays, cameras, speakers and microphones.

Terminal UI

The shell communicates with the core services using the Web Thing Protocol. This also means that terminals can act as web things themselves, so that they can be remotely controlled over the network.

Devices

Devices

Devices are the sensors and actuators which interface with the physical world. That could be a motion sensor, door sensor, smoke alarm, smart socket or a light bulb for example.

Devices may natively be web things, or may be bridged to the Web of Things by the hub, from a range of different protocols like Zigbee, Z-Wave, HomeKit, Matter, BACnet and Modbus.

Either way every device has a URL on the Web of Things which acts as a globally unique identifier and resolves to a machine readable WoT Thing Description. The Thing Description describes the capabilities of the device in a machine readable format and provides URL endpoints with which to communicate with it.

Implementation

Interested? Come and join us in the WebThings open source community where Krellian are building the key components which will eventually make up “Krellian OS”, including WebThings Gateway and WebThings Shell.


  1. The name Krellian is actually inspired by the 1956 science-fiction film Forbidden Planet. Krellian meaning “of or belonging to the Krell”. The Krell were an ancient alien race who created “The Great Machine” on Altair IV, a vast underground machine controlled by thought and capable of monitoring and affecting change throughout the whole planet. The machine continued to function autonomously for thousands of years after the Krell themselves went extinct. It serves as both an inspiration and a warning. ↩︎

What is a Web App?

What is a web app? What is the difference between a web app and a web site? What is the difference between a web app and a non-web app?

In terms of User Experience there is a long continuum between “web site” and “web app” and the boundary between the two is not always clear. There are some characteristics that users perceive as being more “app like” and some as more “web like”.

The presence of web browser-like user interface elements like a URL bar and navigation controls are likely to make a user feel like they’re using a web site rather than an app for example, whereas content which appears to run independently of the browser feels more like an app. Apps are generally assumed to have at least limited functionality without an Internet connection and tend to have the concept of residing in a self-contained way on the local device after being “installed”, rather than being navigated to somewhere on the Internet.

From a technical point of view there is in fact usually very little difference between a web site and a web app. Different platforms currently deal with the concept of “web apps” in all sorts of different, incompatible ways, but very often the main difference between a web site and web app is simply the presence of an “app manifest”. The app manifest is a file containing a collection of metadata which is used when “installing” the app to create an icon on a homescreen or launcher.

At the moment pretty much every platform has its own proprietary app manifest format, but the W3C has the beginnings of a proposed specification for a standard “Manifest for web applications” which is starting to get traction with multiple browser vendors.

Web Manifest – Describing an App

Below is an example of a web app manifest following the proposed standard format.

http://example.com/myapp/manifest.json:

{
  "name": "My App",
  "icons": [{
    "src": "/myapp/icon.png",
    "sizes": "64x64",
    "type": "image/png"
  }],
  "start_url": "/myapp/index.html"
}

The manifest file is referenced inside the HTML of a web page using a link relation. This is cool because with this approach a web app doesn’t have to be distributed through a centrally controlled app store, it can be discovered and installed from any web page.

http://example.com/myapp/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>My App - Welcome</title>
    <link rel="manifest" href="manifest.json">
    <meta name="application-name" content="My App">
    <link rel="icon" sizes="64x64" href="icon.png">
...

As you can see from the example, these basic pieces of metadata which describe things like a name, an icon and a start URL are not that interesting in themselves because these things can already be expressed in HTML in a web standard way. But there are some other other proposed properties which could be much more interesting.

Display Modes – Breaking out of the Browser

We said above that one thing that makes a web app feel more app like is when it runs outside of the browser, without common browser UI elements like the URL bar and navigation controls. The proposed “display” property of the manifest allows authors of web content which is designed to function without the need for these UI elements to express that they want their content to run outside of the browser.

http://example.com/myapp/manifest.json:

{
  "name": "My App",
  "icons": [{
    "src": "/myapp/icon.png",
    "sizes": "64x64",
    "type": "image/png"
  }],
  "start_url": "/myapp/index.html"
  "scope": "/myapp"
  "display": "standalone"
}

The proposed display modes are “fullscreen”, “standalone”, “minimal-ui” and “browser”. The “browser” display mode opens the content in the user agent’s conventional method (e.g. a browser tab), but all of the other display modes open the content separate from the browser, with varying levels of browser UI.

There’s also a proposed “orientation” property which allows the content author to specify the default orientation (i.e. portrait/landscape) of their content.

App Scope – A Slice of the Web

In order for a web app to be treated separately from the rest of the web, we need to be able to define which parts of the web are part of the app, and which are not. The proposed “scope” property of the manifest defines the URL scope to which the manifest applies.

By default the scope of a web app is anything from the same origin as its manifest, but a single origin can also be sliced up into multiple apps or into app and non-app content.

Below is an example of a web app manifest with a defined scope.

http://example.com/myapp/manifest.json:

{
  "name": "My App",
  "icons": [{
    "src": "/myapp/icon.png",
    "sizes": "64x64",
    "type": "image/png"
  }],
  "start_url": "/myapp/index.html"
  "scope": "/myapp"
}

From the user’s point of view they can browse around the web, seamlessly navigating between web apps and web sites until they come across something they want to keep on their device and use often. They can then slice off that part of the web by “bookmarking” or “installing” it on their device to create an icon on their homescreen or launcher. From that point on, that slice of the web will be treated separately from the browser in its own “app”.

Without a defined scope, a web app is just a web page opened in a browser window which can then be navigated to any URL. If that window doesn’t have any browser-like navigation controls or a URL bar then the user can get stranded at a dead on the web with no way to go back, or worse still can be fooled into thinking that a web page they thought was part of a web app they trust is actually from another, malicious, origin.

The web browser is like a catch-all app for browsing all of the parts of the web which the user hasn’t sliced off to use as a standalone app. Once a web app is registered with the user agent as managing a defined slice of the web, the user can seamlessly link into and out of installed web apps and the rest of the web as they please.

Service Workers – Going Offline

We said above that another characteristic users often associate with “apps” is their ability to work offline, in the absence of a connection to the Internet. This is historically something the web has done pretty badly at. AppCache was a proposed standard intended for this purpose, but there are many common problems and limitations of that technology which make it difficult or impractical to use in many cases.

A new, much more versatile, proposed standard is called Service Workers. Service Workers allow a script to be registered as managing a slice of the web, even whilst offline, by intercepting HTTP requests to URLs within a specified scope. A Service Worker can keep an offline cache of web resources and decide when to use the offline version and when to fetch a new version over the Internet.

The programmable nature of Service Workers make them an extremely versatile tool in adding app-like capabilities to web content and getting rid of the notion that using the web requires a persistent connection to the Internet. Service Workers have lots of support from multiple browser vendors and you can expect to see them coming to life soon.

The proposed “service_worker” property of the manifest allows a content author to define a Service Worker which should be registered with a specified URL scope when a web app is installed or bookmarked on a device. That means that in the process of installing a web app, an offline cache of web resources can be populated and other installation steps can take place.

Below is our example web app manifest with a Service Worker defined.

http://example.com/myapp/manifest.json:

{
  "name": "My App",
  "icons": [{
    "src": "/myapp/icon.png",
    "sizes": "64x64",
    "type": "image/png"
  }],
  "start_url": "/myapp/index.html"
  "scope": "/myapp"
  "service_worker": {
    "src": "app.js",
    "scope": "/myapp"
  }
}

Packages – The Good, the Bad and the Ugly

There’s a whole category of apps which many people refer to as “web apps” but which are delivered as a package of resources to be downloaded and installed locally on a device, separate from the web. Although these resources may use web technologies like HTML, CSS and Javascript, if those resources are not associated with real URLs on the web, then in my view they are by definition not part of a web app.

The reason this approach is commonly taken is that it allows operating system developers and content authors to side-step some of the current shortcomings of the web platform. Packaging all of the resources of an app into a single file which can be downloaded and installed on a device is the simplest way to solve the offline problem. It also has the convenience that the contents of that package can easily be reviewed and cryptographically signed by a trusted party in order to safely give the app privileged access to system functions which would currently be unsafe to expose to the web.

Unfortunately the packaged app approach misses out on many of the biggest benefits of the web, like its universal and inter-linked nature. You can’t hyperlink into a packaged app, and providing an updated version of the app requires a completely different mechanism to that of web content.

We have seen above how Service Workers hold some promise in finally solving the offline problem, but packages as a concept may still have some value on the web. The proposed “Packaging on the Web” specification is exploring ways to take advantage of some of the benefits of packages, whilst retaining all the benefits of URLs and the web.

This specification does not explore a new security model for exposing more privileged APIs to the web however, which in my view is the single biggest unsolved problem we now have left on the web as a platform.

Conclusions

In conclusion, a look at some of the latest emerging web standards tells us that the answer to the question “what is a web app?” is that a web app is simply a slice of the web which can be used separately from the browser.

With that in mind, web authors should design their content to work just as well inside and outside the browser and just as well offline as online.

Packaged apps are not web apps and are always a platform-specific solution. They should only be considered as a last resort for apps which need access to privileged functionality that can’t yet be safely exposed to the web. New web technologies will help negate the need for packages for offline functionality, but packages as a concept may still have a role on the web. A security model suitable for exposing more privileged functionality to the web is one of the last remaining unsolved challenges for the web as a platform.

The web is the biggest ecosystem of content that exists, far bigger than any proprietary walled garden of curated content. Lots of cool stuff is possible using web technologies to build experiences which users would consider “app like”, but creating a great user experience on the web doesn’t require replicating all of the other trappings of proprietary apps. The web has lots of unique benefits over other app platforms and is unrivalled in its scale, ubiquity, openness and diversity.

It’s important that as we invent cool new web technologies we remember to agree on standards for them which work cross-platform, so that we don’t miss out on these unique benefits.

The web as a platform is here to stay!