Skip to content
Ecom

How to Do a Shopify App Audit Without Breaking the Store

A safe Shopify app audit protocol from a 250 plus store agency. Staging clones, non destructive DevTools simulation, orphan webhook checks, and rollback.

By WitsCode10 min read

Every merchant we talk to already knows they have too many apps. They know the store is slow, they know the admin is a graveyard of free trials that never got cancelled, and they know at least three of the installed apps are doing nothing except burning 200 kilobytes of JavaScript on every product page. They do not audit anyway. The reason is almost never laziness. The reason is fear.

The fear is specific. Uninstalling the wrong app kills the Meta pixel, drops the reviews off every product page, or erases metafields that a theme customization depends on. A Shopify app audit, done properly, never touches the live store until the last possible moment. This article is the staging protocol we use on every takeover. What to clone, what to test, what logs to keep, and how to roll back.

Why Almost Every Shopify App Audit Breaks Something

The standard audit workflow taught on YouTube goes like this. Open the Apps tab. Uninstall anything you do not recognise. Refresh the storefront. Hope nothing fell off. That workflow survives because most of the time it works. When it fails, it fails silently. A pixel that stops firing on Tuesday does not surface as a problem until the next monthly reporting cycle, by which point the cause and the effect are two weeks apart and the founder is chasing ghosts.

The reason uninstall is a landmine is that Shopify does not enforce clean app removal. When an app is uninstalled, Shopify invalidates the access token and triggers an APP_UNINSTALLED webhook to the app vendor. The vendor is supposed to clean up, but the access token they would need to clean up metafields and theme code is already dead. The result is that metafields persist, snippet files in your theme folder persist, inline script blocks in theme.liquid persist, and, in some cases, webhook subscriptions persist if they were registered through a custom backend rather than the app configuration file. You did not uninstall the app. You removed the billing relationship and left the code.

The apps that use modern App Embeds clean up properly, because disabling the embed removes the theme injection. The apps that use the legacy ScriptTag API, which Shopify is deprecating non Plus access to in August 2026, do not. A majority of older, heavier apps still ship the legacy path. If your store has been accreting apps since 2022, you are sitting on both.

The Staging Environment We Actually Use

The staging environment debate on Shopify has three camps. Camp one duplicates the theme inside the same store, password protects the storefront, and calls that staging. Camp two spins up a free Shopify development store and copies the theme across. Camp three uses a paid staging clone tool like Rewind Staging or Replay to mirror the entire store. Each has tradeoffs and each has a correct use case.

For a pure performance or code audit, we use the duplicated theme approach inside the live store. The command is shopify theme duplicate, available in the Shopify CLI, which clones the live theme exactly, including every section, block, and asset, under a new name. We rename the clone to AUDIT plus the date plus our initials, which gives us a git style provenance trail inside the theme list. The duplicated theme is unpublished, so no customer sees it, and we preview it through the theme editor using its preview link. This covers most audits because the apps we are testing still fire on the preview, the metafields are live, and the only thing we are changing is the theme code.

For audits where we need to actually uninstall an app and observe the consequences, the duplicated theme approach is not enough, because uninstalling an app on a live store uninstalls it for everyone. That is where a true dev store comes in. We clone the theme to a new development store using shopify theme pull followed by shopify theme push to the target. We then install a minimum viable set of the same apps on the dev store, restore the critical metafields using a CSV export from the live store, and run destructive tests there. The dev store will never fully match production because customer data, order history, and live app configuration are not portable, but for app removal rehearsal it is close enough to surface the dependency graph before we touch the real store.

For Plus merchants with revenue at stake, we add the third layer. A full Rewind snapshot is taken, and the audit is executed on the live store with the rollback path pre staged. That is the only scenario where we touch production directly, and even then the clone exists as the escape hatch.

The Non Destructive Preview Most Audits Miss

The single most useful technique in this entire workflow is one that almost no SEO article about Shopify app audits mentions. You can simulate an app uninstall without actually uninstalling the app, using the DevTools request blocking feature on the duplicated theme preview. This is how we give a merchant a defensible before and after number without ever putting the store at risk.

The method is straightforward. Open the duplicated theme preview in Chrome. Open DevTools. Go to the Network tab, right click on any request that originates from an app domain, and choose Block Request Domain. Reload the page. Every subsequent request to that domain is suppressed at the browser level, exactly as it would be if the app were uninstalled and no longer loading its script. Run Lighthouse on the page with mobile and four times CPU throttling, capture the score, then unblock and repeat for the next app. You are building a table of impact without touching the app list.

The power of this pattern is that it surfaces hidden dependencies before you are committed. A social proof app that blocks render adds 400 milliseconds to LCP. Block it in DevTools, reload, read the exact delta. A chat widget that only gets used on the contact page adds 300 milliseconds of main thread time everywhere else. Nothing on the live store has changed. The merchant sees the number. The conversation about removal is now evidence based rather than opinion based.

The caveat is that request blocking only simulates the script not loading. It does not simulate the absence of theme code the app injected, or the absence of metafields, or the absence of server side logic the app runs. For a complete picture you still need to rehearse the uninstall on a dev store. But as a first pass, request blocking gives you ninety percent of the signal with zero percent of the risk, which is the best ratio in this entire protocol.

The Orphaned Webhook Problem

An audit that stops at the theme layer is incomplete, because the nastiest residue an uninstalled app can leave behind is a webhook subscription pointing to a dead callback URL. Shopify retries failed webhook deliveries for up to forty eight hours, then exponentially backs off, and eventually a store with dozens of dead subscriptions will start to see real events get queued behind retries. We have seen a merchant whose ORDERS_CREATE webhook to a payment reconciliation app that had been uninstalled eighteen months earlier was still being fired, failing, and retried, on every order.

The audit path is to list every webhook subscription registered on the store and match it against the current app list. The Shopify CLI command shopify app webhook list will output the subscribed topics for an app in development. For a production orphan check, we query the Admin GraphQL API with the webhookSubscriptions query, which returns every subscription, the topic, the callback URL, and the creation date. We then match the callback URL hostname against the hostnames of currently installed apps. Anything that does not match is a candidate for deletion.

The deletion is not automatic. You delete the subscription by calling webhookSubscriptionDelete with the subscription ID. Before we delete, we confirm the callback URL is not a service the merchant still pays for separately, because a handful of apps route webhooks through custom backends. We log every deleted subscription ID and timestamp in the audit spreadsheet.

The Shopify Flow Pre Audit Snapshot Pattern

The other log layer we build before any audit is a Shopify Flow snapshot. Flow is Shopify's native automation product, free on Plus and Advanced since 2023, and it has an HTTP action that almost no merchant uses for this purpose. We build a single manually triggered workflow that writes a timestamped row to a Google Sheet containing the values we are about to risk. The total product count, the total customer count, the count of metafields per namespace, the active app charge IDs, the published theme ID, and the full list of webhook subscription IDs. The workflow runs in under sixty seconds.

The value is not the snapshot itself. The value is that the snapshot is a contract. If, three days after the audit, the merchant says the conversion rate dropped, we can compare the current state to the snapshot and identify what changed. If the metafield count in a specific namespace is lower, we know an app removal took data with it. If the webhook list is shorter, we know a subscription we thought was orphaned was actually in use. This is how you win the argument about whether the audit caused the problem, because most of the time the problem was already there and the audit just brought it into view.

On stores without Flow access we do the equivalent with a Python script hitting the Admin GraphQL API. The mechanism does not matter. The discipline of a timestamped, externally stored snapshot is what separates a safe audit from a liability.

The Specific Theme Residue You Have To Remove By Hand

When you finally do uninstall, the theme will not clean up after itself. We check four specific locations on every post uninstall pass. The first is theme.liquid, specifically the head and the bottom of body. Apps that injected script tags through the legacy code installation path left them here, and the uninstall does not remove them. You will see comment blocks like BEGIN APP BLOCK or BEGIN KLAVIYO ONSITE wrapping inline JavaScript or script src references to a CDN that no longer serves the store. Delete those blocks, commit the theme, and move on.

The second location is the snippets folder. Apps commonly create files like review-widget.liquid, yotpo-reviews.liquid, klaviyo-onsite-v2.liquid, or similar, and render them from section files using a Liquid render tag. After uninstall the file stays, the render tag stays, and the page still tries to pull a snippet that references assets no longer present. Search the repo for the app's name and for asset_url references to the app's asset filenames, then remove both sides of the reference.

The third location is the assets folder. Some older apps uploaded JavaScript and CSS files directly to the theme asset folder rather than loading from their own CDN. These files persist forever unless removed by hand. They are also a security concern, because an asset bundle from 2021 is not getting patched and if it included any third party dependency with a disclosed CVE, you now own the CVE. We delete any asset file whose name matches the departed app.

The fourth location, on Plus stores, is checkout.liquid, which still exists on upgrade path stores that have not yet migrated to checkout extensibility. Apps that injected pixels or analytics scripts there leave residue that is hard to spot because checkout.liquid is rarely edited. We diff checkout.liquid against the parent theme's original version and remove anything that is not in the original and not tied to a still installed app.

Rollback, The Part Nobody Plans For Until They Need It

A rollback plan is not a line item on a checklist. It is a decision tree that the engineer runs in the moment the storefront breaks, with a timer running and a merchant on Slack. We prebuild it. The tree has three branches. If the problem is visual and contained to the theme, we revert by publishing the BACKUP Live theme we duplicated before the audit. This takes under a minute and returns the storefront to the exact state it was in when we started. If the problem is missing data, specifically a missing metafield or metaobject value, we restore from the Rewind or BackupMaster snapshot taken immediately before the audit. This takes under five minutes per namespace. If the problem is a missing app feature, we reinstall the app from the App Store, which preserves the app's backend configuration in most cases, then verify against the pre audit snapshot.

The app reinstall is the branch that surprises merchants. Most apps keep their configuration on their own servers keyed to the store domain, so uninstall followed by reinstall within a short window recovers the setup. The exceptions are apps that wipe configuration on uninstall as a privacy feature. Those are documented in the app's data handling policy, which is why we read the policy of every app we plan to remove before we remove it. The seven day grace period on most app reinstalls is the margin that makes this protocol forgiving.

Where This Leaves You

A Shopify app audit is not a dangerous operation. It is a dangerous operation when done on a live store with no staging, no snapshot, no simulation, and no rollback plan. The protocol above removes every one of those risks. Duplicate the theme. Run the non destructive DevTools simulation first. Audit webhooks against the live app list. Snapshot with Flow or a script before you touch anything. Clean the four residue locations after uninstall. Keep the backup theme for thirty days minimum.

If this sounds like engineering work rather than admin clicking, that is the point. WitsCode runs this exact protocol as a fixed scope Shopify app audit engagement for UK and US merchants who cannot afford a broken checkout to find out why their store is slow. We bring the staging, the snapshot, the simulation, and the rollback plan. You bring the decision about which apps to keep.

Get weekly field notes.

Practical writing on shipping products, straight to your inbox. No spam.

Need help with this?

Shopify Development

We design and build web apps, MVPs, and SaaS products. Talk to us about what you are working on.

Talk to us

Want to discuss ecom for your business?

Start a project and we'll talk through where you are, what's working, and the highest-leverage moves for the next 90 days.