Every WordPress site leaks information about itself. The generator meta tag, asset URL patterns, REST API fingerprints, and default script handles all broadcast what themes and plugins are running. A WordPress theme detector or plugin detector tool scrapes that broadcast and converts it into a readable stack list. This article breaks down exactly how each major detector works at the HTTP and DOM level, where they fail, and what you can do to clean up your own site’s signal.
Why WordPress Stack Detection Works At All
Before comparing tools, you need to understand the detection surface. WordPress exposes stack information through at least five distinct channels:
- Generator meta tag:
<meta name="generator" content="WordPress 6.5.2">is output bywp_head()unless a plugin or theme removes it. - Asset URL paths: Scripts and styles enqueued via
wp_enqueue_script()typically include the plugin or theme folder name, e.g./wp-content/plugins/woocommerce/assets/js/... - Script handle names: The
idattribute on enqueued<script>tags follows the handle name:<script id="woocommerce-js"> - CSS class signatures: Themes and plugins add predictable classes to
<body>and wrapper elements:theme-twentytwentyfour,elementor-default, etc. - REST API namespace exposure:
/wp-json/returns the full list of registered namespaces, and plugins register their own:/wp-json/wc/v3/,/wp-json/buddypress/v2/.
Each detector tool uses a subset of these channels. The ones with larger pattern databases will catch more plugins, but no tool catches everything because detection depends entirely on observable artifacts.
WPThemeDetector: The Specialist
WPThemeDetector (wpthemedetector.com) was built specifically for WordPress and that focus shows. Its detection logic is tuned to the WordPress asset structure rather than being a general web-tech fingerprinter.
How It Works
WPThemeDetector sends a fetch to the target URL and parses the HTML response. It pulls the generator meta tag to confirm WordPress and extract the version. For theme detection, it inspects the active stylesheet URL: <link rel="stylesheet" href="https://example.com/wp-content/themes/THEME-NAME/style.css">. If a child theme is active, the parent theme’s stylesheet_directory will be referenced for parent template files, so it often catches both.
For plugin detection, it matches enqueued asset paths against a local database of known plugin folder names. The URL pattern /wp-content/plugins/PLUGIN-SLUG/ is a reliable signal. It also cross-references stylesheet handles, script IDs, and inline variable names (e.g., var wc_ajax_url placed by WooCommerce).
Accuracy and Limits
WPThemeDetector is strong on theme identification and decent on plugins that load front-end assets. It misses admin-only plugins entirely. A plugin that never enqueues front-end assets or injects content into public pages is invisible to it. The same applies to any plugin that loads assets conditionally (e.g., WooCommerce only loads its scripts on product and cart pages).
Signal Checked | Detected |
|---|---|
Generator meta tag | Yes |
Theme stylesheet URL | Yes |
Enqueued plugin asset paths | Yes (public pages only) |
REST API namespaces | No |
Admin-only plugins | No |
Child themes | Partial (recognizes child, may miss parent) |
BuiltWith: The Enterprise Fingerprinter
BuiltWith (builtwith.com) is not a WordPress-specific tool. It tracks the entire technology stack for over 650 million websites and is the most commercially focused of the detectors covered here.
How It Works
BuiltWith crawls sites regularly and maintains a persistent database of historical and current technology usage. When you query a domain, it returns data from its crawl cache, not a live scan. Its fingerprinting logic checks:
- HTTP response headers:
X-Pingback,Link(withrel="https://api.w.org/"), server software headers - HTML meta tags including
generator - Script and link element
src/hrefattributes with path-based matching - Cookie names set by the application (e.g.,
wordpress_logged_in_*) - SSL certificate metadata and DNS records
BuiltWith is particularly good at detecting CDN providers, hosting companies, analytics platforms, payment gateways, and ad networks, which are all visible through their script domains and DNS configuration. This makes it more useful for competitive research than for plugin-level detection.
Accuracy and Limits
BuiltWith data can be weeks or months stale because it relies on crawl schedules rather than live requests. A plugin removed last month may still appear in BuiltWith results. Conversely, a recently installed plugin may not appear for weeks. For live “what is this site running right now” questions, BuiltWith is the wrong tool. For “what did this competitor use 3 months ago and what trend does that reflect” it is hard to beat.
IsItWP: Confirming WordPress Before Going Deeper
IsItWP (isitwp.com) is a lightweight WordPress-specific tool. Its primary function is confirming whether a site runs WordPress at all, then surfacing the theme and a short list of visible plugins.
How It Works
IsItWP makes a live request to the target URL and checks for four WordPress confirmation signals:
- The presence of
/wp-content/in any resource URL - The generator meta tag
- The
Link: <https://site.com/wp-json/>; rel="https://api.w.org/"HTTP header - The
X-Pingbackresponse header
For theme detection it reads the stylesheet URL and looks up the theme in the WordPress.org theme repository to surface name, author, and version. For plugins, it matches asset paths against a curated pattern list.
IsItWP’s plugin list is smaller than WPThemeDetector’s because it leans toward commercially known plugins rather than building exhaustive pattern coverage. You will get accurate results for the 50 most common plugins and patchy results for everything else.
Wappalyzer: The Browser-Layer Fingerprinter
Wappalyzer (wappalyzer.com) is a browser extension and API service. The extension runs JavaScript inside the browser context, which gives it access to rendered DOM and JavaScript globals that server-side scrapers cannot see.
How It Works
Wappalyzer uses a community-maintained, open-source pattern file (technologies.json in the wappalyzer/wappalyzer GitHub repository) that defines fingerprinting rules for thousands of technologies. Each rule can match against:
- HTML: Patterns matched against the raw HTML source
- Scripts: Patterns matched against script source URLs
- CSS: Patterns matched against stylesheet URLs
- Headers: HTTP response header value patterns
- Cookies: Cookie name and value patterns
- JavaScript: Global variable existence checks (e.g.,
window.wc_cart_params) - DOM: CSS selector presence checks on the rendered page
- Meta: Meta tag content patterns
The JavaScript and DOM matching rules are what set Wappalyzer apart from server-side tools. A plugin that sets window.wpforms = {nonce: "..."...} will be detected by a JavaScript global check even if none of its assets have a recognizable URL path.
Accuracy and Limits
Wappalyzer is the most accurate detector for technologies with front-end JavaScript presence. Its pattern database is also the most actively maintained of the tools listed here. The trade-off is that it requires the page to fully render in a browser. Server-side JavaScript execution (SSR/ISR setups, headless WordPress) can fool it because the JS globals it checks may be absent or transformed.
Wappalyzer also tends to produce a lot of output: CDN, analytics, A/B testing tools, font services, and widget libraries all appear alongside the WordPress plugins. This is useful for broad competitive intelligence but noisy if you only care about the WordPress plugin stack.
WhatRuns: The Browser Extension Alternative
WhatRuns (whatruns.com) is a browser extension that competes directly with Wappalyzer. Its detection approach is similar but its pattern database is structured differently, which means the two tools occasionally disagree on what a given site is running.
How It Works
WhatRuns performs detection in the browser context and matches against patterns in script URLs, CSS paths, DOM element signatures, HTML comments, and JavaScript global variables. Its WordPress-specific detection includes theme detection via stylesheet path and plugin detection via asset URLs.
One feature WhatRuns offers that most competitors do not is change tracking: it can notify you when a site adds or removes a technology. This is useful for monitoring competitor sites.
Accuracy and Limits
WhatRuns has a smaller pattern database than Wappalyzer and its WordPress plugin coverage is more limited. It identifies the obvious high-traffic plugins reliably but gaps appear quickly for less common or custom plugins. It shares Wappalyzer’s blindness to server-side-only plugins and admin-only tools.
Browser DevTools: The Manual Method That Beats Them All
Every tool above automates what you can do manually in browser DevTools. Doing it manually is slower but more thorough and gives you complete control over what signals you are reading.
Network Tab: Read Every Request
Open DevTools, go to the Network tab, hard-reload the page (Cmd+Shift+R / Ctrl+Shift+R to bypass cache), then filter by JS and CSS. Every enqueued script and stylesheet shows its full URL. Scan for /wp-content/plugins/SLUG/ and /wp-content/themes/SLUG/ patterns. You will see the actual plugin folder names directly.
Also check the response headers on the initial HTML request. The Link header containing rel="https://api.w.org/" confirms WordPress. Security plugins often add or remove response headers, so their presence or absence is itself a signal.
Console Tab: Check JavaScript Globals
In the browser console, you can enumerate JavaScript globals that plugins set. Common ones to check:
These globals are set by plugins even when asset URL paths have been renamed or minified into a build bundle. A site running Elementor will have elementorFrontendConfig regardless of whether its script URL has been obscured.
REST API: Read the Namespace Registry
Navigate to https://example.com/wp-json/ in your browser. The response is a JSON object listing every registered REST namespace. If WooCommerce is active, you will see /wc/v3/. If BuddyPress is active, you will see /buddypress/v2/. If a plugin has a custom REST API, its namespace will appear here.
This endpoint is one of the richest detection surfaces and most automated tools do not use it. It can be disabled by plugins like Disable REST API, but it is open on the vast majority of WordPress sites.
Reading this endpoint is exactly the kind of hands-on inspection technique covered in the WordPress Application Passwords: REST API Guide for Developers on this site, where we walk through the full authentication and namespace structure of the WordPress REST API.
Accuracy Comparison Across Tools
Here is how the tools compare across the main detection surfaces:
Tool | Live scan | JS globals | REST namespaces | Header checks | WP plugins DB size | Data freshness |
|---|---|---|---|---|---|---|
WPThemeDetector | Yes | No | No | Partial | Medium | Live |
BuiltWith | No (cached) | No | No | Yes | Large (not WP-specific) | Weeks-months stale |
IsItWP | Yes | No | Yes (confirmation only) | Yes | Small (top plugins) | Live |
Wappalyzer | Yes (browser render) | Yes | No | Yes | Large | Live |
WhatRuns | Yes (browser render) | Yes | No | Yes | Medium | Live |
DevTools (manual) | Yes | Yes | Yes | Yes | N/A (you read directly) | Live |
For thorough stack detection, run Wappalyzer (or WhatRuns) to catch JS globals and rendered DOM signals, then manually check the REST API namespace endpoint, then scan the Network tab for any asset paths the extension may have missed. No single automated tool covers all five detection channels.
What These Tools Cannot Detect
Knowing the limits of detection tools matters as much as knowing what they can find. There are four categories of stack elements that reliably defeat automated detectors:
1. Admin-Only Plugins
Plugins that operate entirely within wp-admin (backup plugins, staging plugins, development environment tools, security scanners that do not add front-end assets) produce no observable signals on public pages. WP-CLI, ManageWP, MainWP, Updraft Plus, Duplicator, All-in-One WP Migration, and similar tools are essentially undetectable from the public side.
2. White-Labeled or Renamed Plugins
A plugin whose folder is renamed from woocommerce to ecommerce-engine will not match against any detector’s pattern database for WooCommerce. White-label agencies routinely do this. The plugin’s JavaScript globals may still leak (WooCommerce’s wc_cart_params global survives a folder rename), but the URL-based patterns all fail.
3. Custom Child Themes
A child theme with a custom folder name (e.g., client-corp-theme) will not match the parent theme pattern. The parent theme’s files will still be loaded from the parent folder, which can expose the parent. But detectors that rely on the active stylesheet URL will see the child theme folder and fail to match it.
4. Bundled and Concatenated Assets
If a site uses a build tool or plugin that concatenates and serves all scripts from a single file like /wp-content/cache/min/123abc.js, asset URL path matching completely fails. The generated URL has no relationship to the original plugin folder names. JavaScript global variables are still present in the concatenated output and will be detectable via Wappalyzer’s JS checks, but URL-based pattern matching is defeated entirely.
How to Hide Your WordPress Stack
If you are on the defensive side of this and want to reduce your site’s detectability, the approach should be layered. Removing a single signal while leaving others intact just makes your stack look incomplete to detectors without actually protecting anything. Here are the main levers:
Remove the Generator Meta Tag
The generator tag is the most obvious signal. Remove it with a single filter. Add the code below to your theme’s functions.php or a site-specific plugin. Since this involves a code snippet that should live in a version-controlled file, the actual implementation is available in the Gist embed below.
The same filter also removes the generator tag from RSS feeds. The the_generator hook covers both HTML output and XML feeds in one pass.
Suppress the REST API Discovery Header
The Link: <https://example.com/wp-json/>; rel="https://api.w.org/" header is sent automatically with every WordPress page response. Removing it does not disable the REST API, it only removes the advertised discovery link. Add this to the same snippet file:
Note: removing this header breaks some plugin compatibility checks that rely on the discovery link. Test after adding it.
Obfuscate the wp-content Path via .htaccess
You can rewrite asset URLs so that /wp-content/plugins/ is exposed as /static/ or any other path. This defeats URL path pattern matching in all the tools above. The Apache rewrite rules to accomplish this without breaking WordPress internally are available in the Gist below.
Be aware: this change requires updating your WordPress configuration to register the new path. The WordPress Codex documents the WP_CONTENT_URL and WP_PLUGIN_URL constants for this purpose. A misconfigured rewrite breaks all front-end asset loading silently.
For a broader set of security-oriented configuration changes including header hardening and login page relocation, the WordPress Security Hardening: The Complete Checklist covers the full defensive surface in one place.
Rename Asset Handles
The id attribute on script tags comes from the registered script handle. If you dequeue and re-enqueue a plugin’s script under a generic handle name, the ID-based pattern matching fails. This is tedious to maintain but effective on high-visibility plugins.
Use a Caching Plugin That Concatenates Assets
As noted above, concatenated assets served from a cache path completely break URL-based detection. LiteSpeed Cache, WP Rocket, and Autoptimize all have CSS/JS concatenation and minification features. Enable them and your plugin asset URLs disappear from the public response entirely.
JavaScript globals still survive concatenation, so Wappalyzer’s JS checks remain effective. Concatenation does not make your stack undetectable, it just defeats the simpler URL-matching tools.
Practical Use Cases for Each Tool
The right tool depends on what question you are actually trying to answer:
- Confirming a site runs WordPress and identifying the theme: WPThemeDetector or IsItWP. Both are WordPress-specific, fast, and accurate for theme detection.
- Full competitive technology stack research: Wappalyzer browser extension + BuiltWith for historical data. Run both to cross-reference.
- Monitoring when a competitor changes their stack: WhatRuns change tracking feature.
- Auditing your own site’s exposure before hardening: Browser DevTools plus a manual REST API namespace check gives you the most complete picture of what is visible.
- Identifying specific plugins on a client site without admin access: Wappalyzer + manual JS global enumeration in the console.
For Plugin and Theme Developers: What You Expose
If you are building plugins or themes, awareness of your detection surface helps with white-label deployments and security-conscious client work:
- Every
wp_register_script()call with a recognizable handle leaks your plugin name. - Every
wp_localize_script()object becomes a named JavaScript global that pattern matchers can key on. - Every
body_class()addition with your plugin slug as a class prefix is visible in Wappalyzer’s DOM checks. - Every REST API namespace registration appears in the
/wp-json/endpoint immediately.
None of these should be avoided by default. They are standard WordPress development conventions. For white-label deliverables, build a configuration layer that lets clients set a custom plugin slug and sanitizes these identifiers. Trying to remove all signals at the core plugin level creates maintenance overhead and breaks third-party integrations that depend on the standard identifiers.
If you want to go deeper on WordPress PHP patterns that affect front-end output, the 10 WordPress Code Snippets Every Developer Should Save has practical examples covering enqueue patterns, filter hooks, and output manipulation techniques that directly relate to the signals covered in this article.
FAQ
Can a WordPress theme detector tell you the exact theme version?
Sometimes. If the generator meta tag includes a version and the theme has not been modified to remove it, yes. Some tools also read the theme’s style.css header directly if that file is publicly accessible, which contains the Version: field. Custom or private themes rarely expose this.
How accurate is Wappalyzer for WordPress plugin detection?
Accurate for high-traffic plugins that maintain entries in the Wappalyzer pattern database. For niche or custom plugins, accuracy drops significantly. The open-source pattern file on GitHub covers roughly 1,500 WordPress-related technologies out of the 50,000+ plugins in the WordPress.org repository.
Does removing the generator meta tag improve WordPress security?
Marginally. It removes one easily-scraped signal that could help an attacker confirm the WordPress version for targeting known CVEs. It does not protect against attacks that don’t require version knowledge (brute force, credential stuffing, file inclusion). Treat it as one layer in a defense-in-depth approach, not a standalone protection.
Can BuiltWith detect a plugin if it only runs on certain pages?
Depends on whether BuiltWith’s crawler visited a page where that plugin loaded assets. WooCommerce loads its scripts on product, cart, and checkout pages. If the crawler only visited the homepage, WooCommerce assets may not appear in BuiltWith’s record.
What is the wordpress plugin detector search volume compared to wordpress theme detector?
Both terms are in the top 10 Google suggestions for the “wordpress detector” query cluster. Theme detector has slightly higher search volume based on available data, which is why most specialized tools lead with theme detection and add plugin detection as a secondary feature. The underlying detection techniques overlap heavily because both use asset URL path matching as a primary signal.
Conclusion
WordPress detector tools are observational instruments, not forensic ones. They read what your site broadcasts publicly and match it against pattern databases. WPThemeDetector and IsItWP work well for theme identification and visible plugin detection. Wappalyzer adds JavaScript global and DOM-level matching that server-side tools miss. BuiltWith gives you historical data for competitive research. Browser DevTools beats all of them for thoroughness on any single site.
No tool catches admin-only plugins, renamed plugin directories, or white-labeled themes. If you want to know exactly what a site runs, the REST API namespace endpoint and manual JS global enumeration are the most reliable methods that automated tools routinely skip.
For your own site, remove the generator meta tag, suppress the REST API discovery header, and consider asset concatenation if full stack concealment is a requirement. None of this replaces a proper security hardening pass, but it reduces your signal density on the most commonly scraped channels.





No comments yet