What a Shopify App Detector Can Actually See on a Store (and What It Can't)
A Shopify app detector reads the public parts of a storefront -- script tags, injected widgets, DOM signatures -- and matches them against a database of known apps. That works for reviews widgets and upsell popups, but it structurally cannot see anything that runs on Shopify's servers instead of in the visitor's browser, which is most of what a serious operation actually depends on. Here's how the detection method works, the two different ways it gets a result wrong, and how to read what it tells you.
A Shopify app detector works by reading the public parts of a storefront -- the script tags, injected widgets, and DOM elements a browser downloads -- and matching their code signatures against a database of known apps. That is a real and useful technique for reviews widgets, upsell popups, and chat tools, all of which have to run in the customer's browser to do their job. It is also a technique with a hard ceiling: anything that runs on Shopify's own servers instead of the visitor's browser leaves no fingerprint at all, and a growing share of what a serious Shopify operation depends on -- inventory sync, checkout customization, order automation -- works exactly that way.
People run these tools to research a competitor's stack before choosing their own apps, to scope out a store before pitching a rebuild, or to sanity-check what a potential client is already paying for. Those are all reasonable uses, and they're also all decisions that get worse if the report is read as a complete inventory. What you're actually looking at is a list of everything the tool's database recognizes among the apps that happen to leave browser-visible traces -- a specific and shrinking subset of what's really installed, because more and more of what a serious Shopify store depends on has moved off the storefront and onto Shopify's own infrastructure by design.
How detection actually works
Every detector in this category -- ShopScan, Fera AI's detector, the free detector at eachspy.com, Koala Inspector, Commerce Inspector, Instant's tool -- runs a version of the same process. It loads a store's public pages, collects the script src attributes, specific DOM classes and IDs, and JavaScript globals the page exposes (things like a distinctive window.RebuyEngine or a script URL pattern unique to one vendor), then checks that list against a maintained database of app fingerprints. EachSpy's tool states it checks a live storefront against "a database of 130+ known Shopify apps"; ShopScan advertises "data on over 2,000 Shopify apps." Neither publishes a false-positive or false-negative rate, and neither needs to for the method to be useful -- reviews apps, subscription widgets, upsell tools, and most marketing pixels genuinely do inject something into the page, and for that category the approach works.
The database size gap between tools matters more than either page lets on. A 130-app database and a 2,000-app database will disagree constantly on the same store, and an app outside a given tool's index reads as absent, not unknown -- there is no third state in the result.
What this method structurally cannot see
Three categories of Shopify functionality run entirely on Shopify's servers or the merchant's own backend, with nothing shipped to the browser for a detector to fingerprint:
- Shopify Functions and checkout UI extensions. Since Checkout Extensibility replaced
checkout.liquid, custom checkout logic -- discount stacking rules, delivery customization, payment method reordering -- runs as small server-side programs that execute inside Shopify's own infrastructure and return structured data Shopify acts on. There is no client-side script to intercept, by design: Shopify's own documentation on apps in checkout describes Functions as running server-side with no rendering at all. A store with a heavily customized, unusually smooth checkout built this way will show a detector nothing, on any plan. - Backend automation. A Shopify Flow workflow that tags high-risk orders, sends a webhook to a 3PL, or triggers a custom app's inventory sync mutation never touches the storefront. We've written about how far Flow's own templates reach before a merchant needs a custom app for exactly this kind of automation, and none of it leaves a trace a browser-based scanner could find, because none of it runs in a browser.
- Admin-only apps. Purchase order tools, staff scheduling, internal reporting dashboards, ERP connectors -- an entire category of apps a merchant genuinely relies on operates only inside
/admin, which a public detector never loads.
EachSpy's detector page gets closest to admitting this, noting that apps that "only run behind the scenes (like inventory or fulfillment tools) won't show up." That's honest as far as it goes, but it doesn't say which categories that excludes or why -- so a reader has no way to judge how much of a competitor's real operation the report is simply silent on.
Why "no apps detected" doesn't mean a lean stack
Run one of these tools against a store that's genuinely running the checkout-time work described above -- a custom discount-stacking Function, a delivery customization extension, a Flow automation routing high-value orders to a priority fulfillment queue -- and the report will come back looking identical to a store running none of it. Nothing distinguishes "we checked and found nothing" from "we couldn't check this at all," because the tool has no signal either way. That's a meaningful blind spot for the exact stores worth researching most: a competitor spending real engineering time on checkout is, almost by definition, not going to be running it through apps a script scanner can see.
The practical effect is that a detector systematically understates the sophistication of the stores doing the most interesting work, and overstates it for stores that lean on a handful of storefront-visible apps instead of custom development. Neither is a flaw in the tool -- it's just what happens when a fingerprinting method built for one category of app gets read as a verdict on the whole store.
Where it also gets the visible layer wrong
Even restricted to apps that do inject browser-side code, detectors produce both false negatives and false positives, and the two have different causes.
False negatives are the database gap described above: an app too new or too small to be indexed reads as not installed. False positives are more interesting, because they trace back to a specific, well-documented Shopify behavior. When a merchant uninstalls an app, Shopify automatically removes anything the app added through its ScriptTag API or as a theme app extension block -- that cleanup genuinely works. What it does not remove is code an app's developer pasted directly into theme.liquid by hand, or metafields the app wrote, because Shopify's mandatory shop/redact webhook only erases data in the app's own database, not anything sitting inside the merchant's theme. We covered the full mechanics of that gap in our piece on what the uninstall webhook actually cleans up. A detector reading that store months later will report an app that hasn't been installed since before the code was written, because the fingerprint it's matching is still sitting in the theme file, running exactly as if the app were live.
That distinction -- ScriptTag API and theme app extensions get cleaned up automatically, hand-pasted snippets and metafields don't -- is also the fastest way to tell whether a "ghost" hit is worth chasing. If a detector reports an app you're certain was removed, the fix isn't reinstalling anything; it's opening theme.liquid, searching for the script domain the detector flagged, and deleting it by hand.
How to actually use a detector's results
Treat the output as a floor, not a ceiling, and read it accordingly:
- Run more than one tool. Because database sizes differ by an order of magnitude, a single detector's "no apps found" for a category just means that tool doesn't recognize what's there -- not that nothing is.
- If a store's checkout does something a detector can't attribute to any app -- reordered payment methods, custom delivery logic, discount combinations that shouldn't be possible -- assume Shopify Functions or a checkout UI extension, not a missed detection. No amount of re-scanning will find it, because there's nothing client-side to find.
- A hit for an app that makes no sense for the store's category (a B2B wholesaler "running" a gift-wrap widget, say) is more likely leftover theme code from a past install than a live app; check the admin's Apps page before assuming the detector is simply wrong.
- For anything backend-shaped -- inventory accuracy, order routing, fulfillment speed -- a detector has nothing to offer either way. That has to come from asking the merchant directly or from the storefront behavior itself, not from a scan.
- If you actually need to know, a browser's own Network tab during checkout will show more than any third-party detector: it surfaces every request the page makes, including ones to domains no fingerprint database has indexed yet. It's slower and it takes some judgment to read, but it isn't capped by someone else's app list.
None of this is useful for deciding whether to install a specific app yourself, which is the other common reason people run these searches. A competitor running an app is weak evidence it's worth trying and no evidence it's worth trying for you -- the honest version of that decision runs on your own store's numbers, not a fingerprint match on someone else's.
None of this makes these tools useless -- for the specific, real category of storefront-visible apps, matching against a large database is a legitimate way to get a fast answer. The mistake is reading a clean or sparse report as "this store runs a lean stack," when it may just mean the store's real complexity lives in places a script scan was never going to reach. If you're evaluating your own store's app stack before a rebuild -- rather than a competitor's from the outside -- the more reliable version of this exercise is opening your own theme code and Apps list side by side, since you don't have to guess at what a detector can't see when you already have the admin access to look directly. That's the same kind of audit work we do before taking on a Shopify build or migration for a client.