#1245: Question: Review manifest-first Web Install API
Discussions
Log in to see TAG-private discussions.
Comment by @marcoscaceres Jul 15, 2026 (See Github)
Couple of quick personal reactions here (not representative of any sort of TAG consensus, and admittedly a little biased), but I don't see any meaningful engagement with WebKit's Position on this matter in the "Community Feedback" section.
Comment by @robpaveza Jul 15, 2026 (See Github)
Hi @marcoscaceres, thanks for your comment. We've had quite a bit of ongoing discussions with the community and other browser vendors, and we recognize that WebKit has had a rather continuous position regarding site-initiated installation flows. I think it's very fair to say that @dmurph has expressed some particularly fair feedback that we believe was in line with our own perspectives. Google is of course organizationally distinct from Microsoft even if we both contribute to Blink; but perhaps that is fair.
Having said so, I also submit that your position "on this matter" is with respect to the capability of user-initiated application install (notably, you referenced the BeforeInstallPromptEvent when commenting on "this matter"), and that issue is currently Closed. @LiaHiscock specifically said:
In the interest of productivity, we'd like to explicitly request technical architecture feedback on this proposal.
Although we are sensitive to the desire to ensure that we have appropriate user intent signals and to afford balance for prompt fatigue, we have quite thorough feedback from independent web developers, alongside experiment data from the Chrome team, which signal positive direction and sentiment toward the capability. That said, we would prefer not to relitigate the question of the capability here, lest we go around in circles.
I believe @LiaHiscock has answered most of the concerns about the capability in the "Re. previous TAG concerns" section. We appreciate your review.
Comment by @marcoscaceres Jul 16, 2026 (See Github)
Right, but this is fundamentally about architecture: does this capability belong in web pages at all is the core question. There’s fundamental disagreement on that amongst implementers precisely because of what “installing” an app means and to whom; plus the implications that has on the capabilities afforded to the web application (e.g., longer lived storage, push notifications, badging, etc.).
Adding install capability shifts how developers funnel users into their apps, which changes how apps are designed.
My feeling is that we need a TAG finding to settle this matter, as we’ve gone around in circles on this for 13+ years.
Comment by @marcoscaceres Jul 16, 2026 (See Github)
Cc'ing @adactio too, as it would be great to get his input here too as we move things along.
OpenedJul 14, 2026
Brand newer TAG Review Update
Hello TAG!👋 @marcoscaceres @torgo @jyasskin
We've been hard at work the last 12 months gathering feedback from the community, addressing your suggestions, and iterating on our proposal. We've made substantial changes and are ready for a new review. Let me know if you'd prefer I open a new issue!
We acknowledge that we may have a fundamental difference of opinion on whether the web should have the capability to install. In the interest of productivity, we'd like to explicitly request technical architecture feedback on this proposal.
Updated explainers
<install>element (manifest-url design): WICG/install-element/explainer-manifest-url.mdWhat changed
The redesigned API is built around minimizing the cross-origin attack surface, which was a point of interest in the original API.
install_url)manifestURL)navigator.install(https://foo.com)navigator.install(https://foo.com/manifest.json)navigator.install()onlynavigator.install()and a declarative method, as explicitly requested by TAG - the<install>elementWhat stayed the same:
install_sourcesandnavigator.getInstalledApps()are still removed.Major change 1 - the manifest-first install model
The new API fetches the manifest directly as a JSON resource -- no HTML document is loaded, parsed, or executed.
As an added convenience, web developers may omit the dictionary of options -
navigator.install();- in which case the currently loaded page's manifest is targeted for installation viabeforeinstallprompt's discovery algorithm.In the interest of security, if the JSON at
manifestdoes not containid, the developer must pass the expected, computed manifest id. See explainer section - A note on manifest id.Security/privacy properties:
manifestmust be same-origin with itsstart_url. CDN-served manifest URLs will not be initially supported, to reduce spoofing risk.install_urldesign (which required loading a full HTML document), the manifest-URL design never executes scripts or loads subresources from the target origin during the install flow.DataError,AbortError,TypeError, etc). No manifest contents, or persistent app identity are leaked to the calling origin.Major change 2 - the
<install>elementResponding directly to TAG's suggestion to consider a declarative approach (and the
reldiscussion from @jyasskin's earlier feedback), we've developed two complementary entry points:navigator.install()API -- for developers who need control over UX, promise-based outcomes, and integration with custom-rendered environments (WebXR, WebGL).<install>element -- for zero-JS usage, with the following properties -The declarative entry point inherits the Permission Element (PEPC) security model:
The imperative
navigator.install()path, by contrast, gates cross-origin installation behind aweb-app-installationpermission (integrating with the Permissions API) -- the appropriate trade-off for a JS-driven flow where the UA cannot make the same assumptions about user intent that a visible, validated element provides.Additional abuse mitigations (both entry points)
Community feedback
Since your last review, we've also been actively engaged with the web developer community, and have received strong positive signals from early adopters:
Progressier (PWA toolkit used by thousands of developers) has integrated Web Install API support
PWAStore.io has also integrated Web install API support, and are active in the PWA community
Google Chat has a use case to promote app install from the app's site, as well as from closely related Google properties (e.g. Gmail) that are cross-origin.
A partner gave feedback after testing that the former
install_urlversion was too brittle, due to the frequent utilization of redirects, which is addressed by the switch tomanifestURL.Open feedback threads: WICG/install-element#23 -- comparing imperative vs. declarative approaches
Re. previous TAG concerns
We want to be transparent about where things stand. This review was previously closed with an Unsatisfied resolution: the same-origin user need was considered clear and strongly supported, but the cross-origin capabilities remained a significant concern, and the recommendation was to ship same-origin first and revisit cross-origin later.
After a further year of developer feedback and two origin trials, we have re-framed this proposal around a single, coherent capability -- the ability to install web apps -- which we believe necessarily spans both same-origin and cross-origin installation. We remain committed to cross-origin as the real, unmet gap in the platform, and we welcome any technical feedback you may have on our new proposal.
Centralization & gatekeeping
The TAG was concerned that cross-origin installation could create centralization or gatekeeping effects -- for example, if a new app store needed the approval of each app before it could install it, that would build a moat around incumbents.
We previously agreed this would be harmful, and have not brought back the mechanism that created it:
install_sourcesis still gone. There is no site-controlled allowlist of who may install an app, so a newly created store is on equal footing with an established one -- no per-app approval, no registry, no gatekeeper.User agency & control
The TAG was concerned about diminished user agency over installation. As described under Additional abuse mitigations, every install requires transient user activation and explicit, UA-controlled consent, is blocked in cross-origin subframes and sandboxed contexts, and is unavailable in private browsing. The user is always the one who decides whether an install happens.
Privacy of cross-origin install signals
The TAG raised the privacy implications of cross-origin install signals -- in particular, exposing whether apps are installed (or later uninstalled) back to a caller. As covered under Major change 1, the design minimizes this surface:
navigator.getInstalledApps()remains removed, the manifest fetch is credential-less (credentials: "omit"), and only coarse promise outcomes are returned -- so no install state, manifest contents, or persistent app identity leak to the calling origin.On limiting the proposal to same-origin only
We acknowledge that the TAG advised limiting the proposal to same-origin. We have heard this clearly. However, we continue to believe cross-origin installation addresses a genuine, unmet need: app directories, search/discovery surfaces, and suites of related apps (same site, cross origin) all depend on one origin being able to offer installation of an app hosted elsewhere. This came through repeatedly in direct developer feedback during the developer trial, and two origin trials we ran.
The manifest
idrequirementThe TAG noted it did not feel the
idoverride mechanism was necessary. Our motivation is that only ~4% of web apps (as of 2024) declare anidin their manifest, yetidis essential to avoid duplicate, un-updatable installs, and ensure users don't miss critical site security updates. For apps that declare anid, the caller may omit it; the override exists only so that apps without a declaredidcan still be installed reliably.Duplication of
beforeinstallpromptThis API is not a duplicate of
beforeinstallprompt.beforeinstallpromptcan only prompt to install the currently loaded web app, requires subscribing to an event and managing its timing, has no cross-origin or declarative story, and is not on a standards track. The Web Install API instead provides an explicit, developer-invoked entry point that can target any app by its manifest URL -- a superset of whatbeforeinstallpromptoffers, delivered through a stable, promise-based (and declarative) surface.This distinction is borne out by developers who have shipped both. Jeremy Keith, who has used both APIs in production, summarizes the comparison bluntly:
beforeinstallprompt"relies on you capturing and delaying an event that may or not fire at all," whereas withnavigator.install(), "based on a user interaction -- like a click on a button -- the browser initiates the installation process. The user still has to confirm… You know how geolocation or web notifications work? It's like that." His verdict:On the "try-before-you-buy" / declarative approach discussion
TAG previously expressed a preference for users to interact with the target site before being prompted to install, and suggested
<a rel="install">as a mechanism that would naturally navigate to the app in non-supporting browsers.We took this feedback seriously and evaluated both paths. We chose
<install>over<a rel="install">(a developer-styled link) for the reasons detailed in the explainer. We want to be transparent that this is a different shape than what TAG suggested, but we believe the security tradeoffs are worth it.That said, we want to highlight a gap in the "navigate first, then install" model: once a user arrives on the target page, installation success rates remain low because the web platform currently provides no standard, discoverable installation entry point on that page. Users must independently discover browser-specific UI (an address bar icon, a menu item, or an ambient prompt), and empirical data from the Origin Trial shows many users never find it. This is the core problem the Web Install API is designed to solve -- and it applies equally whether the user arrived organically or via an
<a>tag navigation.To put numbers to this, browser-controlled installation entry points see very low engagement: Chrome's ambient omnibox install icon has roughly a 0.01% click-through rate, and even browser-initiated install prompts sit around 1.2% (Chrome data, shared by @dmurph in WebKit/standards-positions#619). We read this as a discoverability failure rather than a lack of user interest: when installation depends on users locating browser-specific chrome, the overwhelming majority never do. A standard, site-surfaced entry point is what lets developers place an install affordance where it is actually contextually relevant.
In other words: navigating to the app is valuable for building trust, but it doesn't solve the installation discoverability problem on its own. The
<install>element andnavigator.install()exist precisely to close that gap -- giving both the originating page and the target page a reliable, standard way to trigger installation.We acknowledge that
<install>doesn't enforce a "visit first" model at the platform level. However:<install>itself, such as the app's origin or icon. See<install>'s Open Questions<a>link -- this API doesn't prevent that workflow, it just doesn't mandate it.Conclusion
We'd welcome TAG's re-review and technical feedback on the updated design. We believe the manifest URL approach and the declarative element address the core architectural concerns raised previously. Happy to answer any questions or provide additional detail.
cc @christianliebel @mikewest @dmurph
<!-- Content below this is maintained by @w3c-tag-bot -->Track conversations at https://tag-github-bot.w3.org/gh/w3ctag/design-reviews/1245