The Shopify App Uninstall Webhook Cleans Up Less Than Merchants Assume

By Milan Dhameliya · · 9 min read

Shopify automatically removes an uninstalled app's script tags and theme app extension blocks — that part is genuinely clean. What it doesn't touch is metafields the app wrote, code pasted directly into theme.liquid, and the mandatory "shop/redact" webhook only erases the app's own database, not anything sitting in your store.

Uninstalling a Shopify app automatically removes that app's script tags and any app blocks or embeds it added through theme app extensions — Shopify handles both of those on its own, immediately. What it does not remove is any code the app pasted directly into theme.liquid instead of using Shopify's supported methods, and it does not touch metafields, order tags, or cart attributes the app wrote into your store. Those sit there indefinitely unless someone deletes them by hand.

Most of what gets written about "leftover code after uninstalling a Shopify app" either overstates the mess (treating every app as a permanent liability) or understates it (assuming the uninstall webhook is some kind of general cleanup switch). Neither is accurate, and the difference matters if you're trying to figure out whether your own store actually has a problem.

What Shopify actually removes for you

Two categories of app-installed content are genuinely self-cleaning, and if every app your store has ever used shipped this way, you have little to worry about:

This is the part every merchant should know before assuming the worst: if an app was built and installed within roughly the last three to four years using Shopify's current tooling, uninstalling it is close to a non-event for your theme. The mess people warn about is real, but it's concentrated in older integration patterns and in data categories Shopify was never going to touch automatically.

Why the uninstall webhook can't do more than that

When a merchant uninstalls an app, Shopify fires an app/uninstalled webhook to the app's own server — but by the time that request lands, your store's access token has already been revoked. If the app's own cleanup code tries to call the Admin API from inside that webhook handler to delete anything it previously wrote (a metafield, a customer tag, a saved setting), the call fails with an authentication error. The token is dead before the notification that it's dead even arrives. This is a known, documented friction point for app developers, not an edge case — it's the reason responsible apps try to delete their own data proactively, during use, rather than reactively at uninstall.

Separately, every app distributed through the Shopify App Store must also implement three mandatory compliance webhooks: customers/data_request, customers/redact, and shop/redact. The one merchants tend to assume covers everything is shop/redact, which Shopify sends 48 hours after an uninstall, carrying the shop's ID and domain. Read what it actually instructs the app to do: erase that shop's data from the app's own database. It says nothing about, and has no mechanism for, deleting anything the app wrote into your Shopify store itself — your metafields, your order tags, your theme code. Compliance webhooks govern the app vendor's records about you, not your records.

What actually survives an uninstall

Given the two points above, the realistic leftover list is narrow but specific:

Finding it

Search your theme's actual files for the vendor's script domain or a known snippet name — this catches manually-pasted code that no admin screen will ever surface:

# From a local theme checkout, search every section, layout, and snippet file
grep -ril "cdn.vendorname.com\|vendor-widget.js" sections/ layout/ snippets/ templates/

For metafields, the Admin GraphQL API will show you everything currently attached to the shop, including namespaces from apps you no longer have installed:

query {
  shop {
    metafields(first: 50) {
      edges {
        node { namespace key value }
      }
    }
  }
}

Most apps namespace their metafields with their app handle or API key, so an unfamiliar namespace next to a still-active one is usually your signal. This is the same category of drift our inventory sync coverage deals with elsewhere — Shopify's Admin API behaves in specific, documented ways that quietly diverge from what the interface implies, and orphaned app data is one more example of that pattern rather than a one-off.

A short audit after uninstalling any app

  1. Check the theme customizer's App embeds panel. If it's empty of the uninstalled app, its embed cleaned up correctly. This confirms the theme-app-extension path worked, but it doesn't rule out manually-pasted code sitting elsewhere.
  2. Grep the theme files for the vendor's CDN domain or a distinctive snippet comment, as above. This is the check that catches what the customizer can't show you.
  3. Query shop and product metafields for namespaces that don't map to any app you currently use.
  4. Review Flow workflows that touched the uninstalled app's triggers or actions — a workflow silently not firing is worse than one that errors visibly, because nothing alerts you to check it. We cover the broader gap between what Shopify's Flow trigger documentation implies and what actually happens if you're building around app-provided steps generally.
  5. If the app ever handled EU or UK customer data, get written confirmation from the vendor that shop/redact was processed — that webhook proves their side is clean, but it's still worth a record for your own compliance file, since it's evidence about their database, not proof your store has none of their footprint left.

Leftover, manually-injected script tags are also a genuine performance liability, not just clutter: a script that keeps loading and executing on every page view after the app is gone is dead weight against your Core Web Vitals, and it can keep firing analytics events that duplicate whatever replaced it. If you're not sure whether an old uninstall left something running, our free store audit checks a storefront's actual rendered code for exactly this kind of orphaned script, alongside the other structural issues a scan like that turns up.

Who doesn't need to do any of this

If your store exclusively runs Online Store 2.0 and every app you've ever installed came from the App Store within the last few years using theme app extensions or Web Pixels — never a copy-pasted snippet, never the legacy ScriptTag API — an uninstall is genuinely close to complete. The audit above is worth doing once as a baseline, but it's not something you need to repeat after every routine app swap on a clean, modern stack. The risk concentrates in stores with a longer history: multiple theme migrations, apps installed years ago under older integration patterns, or developers who took the "just paste this in theme.liquid" shortcut because it was faster than building the proper extension.

If that audit turns up more than a script tag or two — genuine ghost code across several old app installs, metafields nobody can identify, workflows quietly broken — that's usually a sign the store needs a proper cleanup pass rather than a one-off grep. That's the kind of work worth talking to a Shopify developer about directly, since it touches theme files, stored data, and automations at the same time.