ScreenshotNeo

BlogHow-to

How to Uninstall a PWA with Puppeteer

Use Puppeteer’s browser-level uninstallPWA API to remove an installed PWA. The PWA APIs require launching Puppeteer with pipe transport.

By the ScreenshotNeo team4 October 20265 min read

To uninstall a Progressive Web App installed through Puppeteer’s PWA workflow, call browser.uninstallPWA({manifestId}). Launch Puppeteer with pipe: true: the browser-level PWA APIs require a pipe connection and are not exposed over a WebSocket connection. Keep the manifest ID returned by installPWA so you can pass it to the uninstall call.

Requirements and scope

The browser-level PWA install, launch, and uninstall methods were added in Puppeteer 25.4.0. Use a release that includes them, and check the API reference for the exact UninstallPWAOptions shape supported by your installed version. The current documentation describes passing the manifest ID returned by installPWA to uninstallPWA. Puppeteer uninstallPWA API · Puppeteer changelog.

This operation applies to a PWA installed using the browser-level Puppeteer PWA workflow. It is not a general command for deleting arbitrary site data, clearing a service worker, uninstalling an extension, or removing an app through the operating system’s settings.

Uninstall a PWA when you have its manifest ID

  1. Use Puppeteer 25.4.0 or later, with the PWA methods available in your version.
  2. Launch Chromium with pipe: true.
  3. Supply the manifest ID for the installed PWA in the version’s documented options shape.
  4. Close the browser with browser.close() when the operation is done.
import puppeteer from 'puppeteer';

const manifestId = 'YOUR_PWA_MANIFEST_ID';
const browser = await puppeteer.launch({ pipe: true });

try {
  await browser.uninstallPWA({ manifestId });
  console.log(`Uninstalled PWA ${manifestId}`);
} finally {
  await browser.close();
}

Save this as uninstall-pwa.mjs and run it in a project where Puppeteer is installed:

node uninstall-pwa.mjs

Replace the placeholder with the ID for the app you installed. The example shows the documented relationship between the returned manifest ID and the uninstall option; it is not a report of a test run. If your installed Puppeteer version’s type documentation specifies a different option shape, follow that reference.

Install and uninstall in one script

If the same script owns the install lifecycle, retain the ID returned by installPWA and pass it directly to uninstallPWA. Consult your installed version’s API reference for the install arguments required by your application.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ pipe: true });

try {
  // Supply the install options required by your Puppeteer version and app.
  const { manifestId } = await browser.installPWA({
    // Add the documented install options for your version here.
  });

  await browser.uninstallPWA({ manifestId });
} finally {
  await browser.close();
}

This lifecycle example is a template because the install options depend on the API version and app. Do not guess those fields: check the installed package’s types and the official installPWA API reference. Retaining the returned ID avoids having to reconstruct it later.

Connection and browser lifecycle details

Use pipe transport

Set pipe: true in puppeteer.launch(). A regular WebSocket connection does not expose this PWA API family. If you connect to an already-running browser through WebSocket, the documented pipe requirement is not satisfied; launch the browser through Puppeteer with pipe transport for this workflow.

Close the browser you launched

browser.close() gracefully closes a browser launched by the script. browser.disconnect() disconnects Puppeteer while leaving the browser process running, so it is not a substitute when your script should stop the browser. Neither browser closure nor disconnection is itself the PWA uninstall operation. Puppeteer browser management.

Contexts and service workers are separate concerns

Closing a browser context closes its pages and isolates cookies and local storage; the documentation does not describe context closure as uninstalling a PWA. Likewise, page.setBypassServiceWorker(true) changes how page requests interact with the service worker. It does not remove the installed PWA. Use browser.uninstallPWA() for the uninstall action. See Page.setBypassServiceWorker.

Troubleshooting

Symptom Likely cause What to do
uninstallPWA is missing or unavailable The installed Puppeteer version predates the PWA methods, or the connected browser transport does not expose them. Use a Puppeteer release with the API (added in 25.4.0) and launch with pipe: true. Check the API reference for that exact version.
The call fails over a remote debugging connection The PWA API family requires pipe transport, not WebSocket. Launch Chromium through Puppeteer using puppeteer.launch({ pipe: true }) for this operation.
The app does not appear to be removed The supplied ID may not identify the PWA installed in that browser, or the app may not have been installed through the expected workflow. Use the manifest ID returned by installPWA and confirm the option shape against the installed version’s UninstallPWAOptions type.
Closing a context or bypassing the service worker had no effect Those actions affect page state or request handling; neither is the PWA uninstall call. Call browser.uninstallPWA({ manifestId }) over the required pipe connection.
The browser process remains after the script The script called browser.disconnect(), which leaves a launched browser process running. Use await browser.close() when the script should gracefully close its launched browser.

Reliability and operational notes

  • Persist the ID: If installation and removal happen in separate runs, store the returned manifest ID alongside the browser profile or test fixture that owns the installed app.
  • Keep the browser context consistent: Run uninstall against the browser/profile in which the PWA was installed. A separate browser launch may not represent the same installed-app state.
  • Make cleanup explicit: In automated jobs, put browser.close() in a finally block so ordinary script failures do not skip browser cleanup.
  • Check version-specific types: Puppeteer releases change over time. Confirm the option types and method availability in the version your project pins.
  • Cost and performance: The cited Puppeteer documentation provides no API-specific cost or performance figures. This is a local browser automation action; runtime and infrastructure cost depend on where and how you run Chromium.

Or skip the browser setup

If your goal is to capture a page while automating a workflow, ScreenshotNeo is a website screenshot API and MCP server. It does not uninstall PWAs; it captures a URL as an image or PDF with one GET request. Its API documentation covers the available options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

Can I uninstall an extension with this method?

No. Puppeteer has a separate browser.uninstallExtension(id) method for extensions. The PWA method is browser.uninstallPWA().

What if I did not save the manifest ID?

Use the exact UninstallPWAOptions supported by your installed Puppeteer version and identify the correct app ID for that browser. The documented straightforward workflow is to retain the ID returned by installPWA.

Does this remove all site data?

The cited API describes uninstalling the PWA. It does not establish that this operation clears every cookie, local-storage entry, or other site data.