Tech Stack Detector: Wappalyzer & BuiltWith Alternative
Pricing
from $2.00 / 1,000 website analyseds
Tech Stack Detector: Wappalyzer & BuiltWith Alternative
Wappalyzer and BuiltWith alternative for bulk URL lists. Detects 7,600+ technologies (CMS, ecommerce, JS frameworks, analytics, CDN, hosting, payments, CRM) with version, confidence score and the exact evidence behind every match. $0.002 per website, no API key or login.
Pricing
from $2.00 / 1,000 website analyseds
Rating
0.0
(0)
Developer
Michal Pšenčík
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Find out what any website is built with. Give this Actor a list of URLs or domains and it returns, for each site, the CMS, ecommerce platform, JavaScript framework, analytics and tag managers, CDN, hosting, web server, payment processor, CRM and marketing tools and more, out of a fingerprint set of 7,600+ technologies in 109 categories. Every match carries its version when the site exposes one, a confidence score, and the evidence: the exact header, cookie, script URL, meta tag or HTML snippet that produced it, so you can check a result instead of trusting it.
It is a Wappalyzer alternative in the literal sense: the fingerprints are the community-maintained Wappalyzer set (enthec/webappanalyzer), run over plain HTTP. No browser extension, no Wappalyzer or BuiltWith subscription, no API key. $0.002 per website.
Try it now: open the Input tab, leave the defaults, and click Start to profile three well-known sites.
Why this tech stack detector
- 7,600+ technologies, not a hand-picked list. Many detectors on the Store check 45 to 250 named technologies. This one evaluates the full Wappalyzer fingerprint set, including Shopify apps and themes, WordPress plugins and themes, consent tools, live chat, A/B testing, CDPs and payment processors.
- Evidence for every match. Each technology lists the header, cookie, meta tag, script URL or HTML pattern that matched, plus the matched value. Wrong-looking results are explainable and easy to filter.
- Versions and confidence.
versionis filled in where the site gives it away (?ver=strings, generator tags, server headers), andconfidencefollows the fingerprint author's weighting, 0 to 100. - Reads the JavaScript too. Besides the page, it downloads up to 8 of the site's script files (up to 30 if you raise it) and searches them, which finds bundled libraries a single HTML fetch misses.
- Built for bulk lists. Plain HTTP with up to 10 sites in parallel: ten sites take about ten seconds and a thousand take a few minutes. One row per website, CSV-friendly columns included.
- Priced per website, platform usage included. $0.002 per site analysed plus $0.005 per run. 10,000 domains cost $20.01.
What data you get
One dataset item per website:
| Field | What it holds |
|---|---|
url | The URL as you supplied it. |
finalUrl | Where it ended up after redirects. |
statusCode | HTTP status of the final response. A 4xx or 5xx page is still analysed, because it still has headers. |
success | Whether the site could be fetched at all. |
error | Why it could not, when it could not. |
technologies | Every detected technology with name, categories, website, version, confidence and evidence, most confident first. |
technologyNames | The same names as a flat list, so CSV and Excel exports stay readable. |
technologyCount | How many technologies were found. |
categories | Every category present on the site, deduplicated. |
scriptsFetched | How many external script files were downloaded and searched. |
detectedAt | When the run started, in UTC. |
Inside technologies, evidence[].type says where a match came from: header, cookie, meta, scriptSrc,
script (inside a downloaded JavaScript file), html, text, css, url, dom, or implied when one
technology necessarily brings another (WordPress implies PHP and MySQL).
Use cases
- Sales prospecting and lead qualification. Filter a list of domains down to the ones running Shopify, HubSpot, WordPress, Stripe or a competitor's product, then hand your team the ones worth calling.
- Lead and CRM enrichment. Run the domains from your signups or your CRM through the Actor and attach the stack to each record.
- Competitive and market research. Count what a list of companies actually runs, rather than what a vendor's case-study page claims.
- Agency audits and pitches. Produce the technology inventory for a prospect from a URL list in one run.
- Security and compliance sweeps. Spot the sites in your estate still advertising an old server version, an outdated jQuery, or a tag manager nobody remembers adding.
- AI agents. Give an agent a tool that answers "what is this site built with?" with checkable evidence (see Use with AI agents).
How to detect a website's tech stack
- Click Try for free (or open the Actor in Apify Console).
- On the Input tab, add your websites to Websites to analyse. Use Bulk edit to paste a list, one
URL per line, or upload a CSV or text file, or link a Google Sheet. A bare domain like
example.comworks; it is read ashttps://example.com. - Leave the rest at the defaults for a first run. Raise Minimum confidence for fewer weak matches; raise Scripts to download per site when a site hides its stack in its JavaScript bundles.
- Click Start.
- Open the Output tab and export as JSON, CSV, Excel or HTML, or fetch the results through the API.
For a recurring inventory, use Schedules in Apify Console to re-run the same list every week and compare the results.
Input
All fields are optional; the defaults profile three sample sites.
| Field | Type | Default | Description |
|---|---|---|---|
startUrls | array | three sample sites | The websites to analyse, as { "url": "..." } objects, or { "requestsFromUrl": "..." } links to a text file, CSV or Google Sheet of them. One dataset item comes back per URL. Duplicates are removed. |
maxItems | integer | 1000 | Stop after this many URLs. 0 means no limit. |
maxScripts | integer | 8 | How many external JavaScript files to download and search per site, 0 to 30. Inline scripts are always searched. 0 makes runs faster. |
minConfidence | integer | 0 | Drop technologies detected below this confidence, 0 to 100. |
includeFailedUrls | boolean | true | Write a row for a URL that could not be fetched, with the error in it. A failed row is a dataset item and is billed as one. Set to false to skip them. |
proxyConfiguration | object | Apify proxy disabled | Optional. The Actor fetches the URLs you supply, so no proxy is needed for most lists. |
Example input:
{"startUrls": [{ "url": "https://wordpress.org" },{ "url": "https://www.shopify.com" },{ "url": "https://stripe.com" }],"maxScripts": 8,"minConfidence": 50,"includeFailedUrls": true}
Output example
The record below is a real run against https://wordpress.org, trimmed to five of the thirteen technologies it
found and to the first two pieces of evidence each.
{"url": "https://wordpress.org/","finalUrl": "https://wordpress.org/","statusCode": 200,"success": true,"error": null,"technologies": [{"name": "WordPress","categories": ["CMS", "Blogs"],"website": "https://wordpress.org","version": "7.2","confidence": 100,"evidence": [{"type": "header","key": "link","pattern": "rel=\"https://api\\.w\\.org/\"","value": "rel=\"https://api.w.org/\""},{"type": "meta","key": "generator","pattern": "^WordPress(?: ([\\d.]+))?","value": "WordPress 7.2"}]},{"name": "Gutenberg","categories": ["WordPress plugins", "Editors"],"website": "https://github.com/WordPress/gutenberg","version": "23.9.0","confidence": 100,"evidence": [{"type": "scriptSrc","pattern": "/wp-content/plugins/gutenberg/","value": "/wp-content/plugins/gutenberg/","source": "https://wordpress.org/wp-content/plugins/gutenberg/build/modules/block-library/navigation/view.min.js?ver=1bf28ded04f9f188bdcb-20240308"},{"type": "dom","key": "link[href*='/wp-content/plugins/gutenberg/'][href]","pattern": "/wp-content/plugins/gutenberg/.+\\.css(?:\\?ver=(\\d+(?:\\.\\d+)+))?","value": "/wp-content/plugins/gutenberg/build/styles/block-library/navigation/style.min.css?ver=23.9.0"}]},{"name": "Nginx","categories": ["Web servers", "Reverse proxies"],"website": "https://nginx.org/en","version": null,"confidence": 100,"evidence": [{"type": "header","key": "server","pattern": "nginx(?:/([\\d.]+))?","value": "nginx"}]},{"name": "Google Tag Manager","categories": ["Tag managers"],"website": "https://www.google.com/tagmanager","version": null,"confidence": 100,"evidence": [{"type": "html","pattern": "googletagmanager\\.com/ns\\.html[^>]+></iframe>","value": "googletagmanager.com/ns.html?id=GTM-P24PF4B\" height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe>"}]},{"name": "MySQL","categories": ["Databases"],"website": "https://mysql.com","version": null,"confidence": 100,"evidence": [{"type": "implied","pattern": "WordPress","value": "implied by WordPress"}]}],"technologyNames": ["Google Font API","Google Tag Manager","Gutenberg","HSTS","MySQL","Nginx","Open Graph","PHP","Priority Hints","RSS","WordPress","WordPress Block Editor","WordPress Site Editor"],"technologyCount": 13,"categories": ["Blogs","CMS","Databases","Editors","Font scripts","Miscellaneous","Page builders","Performance","Programming languages","Reverse proxies","Security","Tag managers","Web servers","WordPress plugins"],"scriptsFetched": 5,"detectedAt": "2026-09-03T17:01:44.906Z"}
A URL that could not be fetched comes back as a row too, so nothing disappears from your list silently:
{"url": "https://this-domain-does-not-exist-98765.com/","finalUrl": null,"statusCode": null,"success": false,"error": "getaddrinfo ENOTFOUND this-domain-does-not-exist-98765.com","technologies": [],"technologyNames": [],"technologyCount": 0,"categories": [],"scriptsFetched": 0,"detectedAt": "2026-09-03T17:02:18.676Z"}
How much does it cost to detect a website's tech stack?
This Actor uses pay per event pricing: $0.002 per website analysed, plus $0.005 per run start. Platform usage is included, so those two numbers are the whole bill.
| Websites in the run | Cost |
|---|---|
| 10 | $0.03 |
| 100 | $0.21 |
| 1,000 | $2.01 |
| 10,000 | $20.01 |
The most-used tech stack Actor on this Store charges $0.10 per detection, so the same 10,000 domains cost $1,000 there.
A few Actors charge less per row. They return a list of names: no version, no confidence and no evidence you can check, and they make one request per site. This one makes up to nine (the page plus its scripts), which is what finds the bundler, the JavaScript library and the analytics tag that a single fetch of the HTML misses.
The Apify free plan comes with $5 of monthly platform credit, which covers around 2,000 websites. To cap spending
on a run, set a maximum cost in the run options, or use the maxItems input.
Use via API
Run the Actor and get the dataset back in one call:
curl -X POST "https://api.apify.com/v2/acts/thatmike1~tech-stack-detector/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{ "startUrls": [{ "url": "https://wordpress.org" }, { "url": "https://www.shopify.com" }] }'
Or from Node.js with the Apify client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('thatmike1/tech-stack-detector').call({startUrls: [{ url: 'https://wordpress.org' }, { url: 'https://www.shopify.com' }],});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const site of items) console.log(site.url, site.technologyNames);
The Python client works the same way. The Actor also plugs into Make, Zapier, n8n, Google Sheets, Slack and webhooks through Apify's integrations.
Use with AI agents (MCP)
Add the Apify MCP server with this Actor as a tool to Claude, Cursor, VS Code or any MCP client:
https://mcp.apify.com?tools=thatmike1/tech-stack-detector
Then ask things like "What CMS and analytics do these five competitors use?" or "Which of these domains run Shopify?". Each answer comes with the evidence behind it, so the agent can show its work.
Tips and advanced options
- Analyse a deep page, not just the home page. A checkout URL reveals the payment processor, a blog post reveals the CMS plugins. The Actor fetches exactly the URL you give it and does not crawl.
- Fast, cheap pass.
maxScripts: 0cuts each site to one request. You keep every header, cookie, meta, HTML and inline-script fingerprint and lose only the ones inside bundled JavaScript files. Raise it to 30 when depth matters more than speed. - Pay only for what was analysed. Set
includeFailedUrls: falseand dead domains cost nothing. - Cut the noise.
minConfidence: 100keeps only technologies backed by a strong or a repeated signal. - Exporting to a spreadsheet? Use
technologyNamesandcategories. The fulltechnologiesarray is nested and flattens badly into CSV. - Deduplicate on
finalUrl. Two input URLs that redirect to the same site produce two rows.
What it can and cannot see
The Actor reads what a site sends over HTTP: response headers, cookies, the HTML, the meta tags, the script URLs, and the contents of the JavaScript files it downloads. Roughly 86% of the fingerprint set can be evaluated that way.
The rest cannot, and the Actor does not pretend otherwise. Fingerprints that need a running JavaScript context (a global variable a framework sets at runtime), a DNS lookup, or a TLS certificate issuer are not evaluated. In practice this mostly costs you single-page applications that leave no trace in their server-rendered HTML.
FAQ
Is this a Wappalyzer alternative? Yes. It runs the community-maintained Wappalyzer fingerprint set, the same kind of patterns the Wappalyzer extension used, minus the ones that need a browser (see above). Wappalyzer's original repository is gone and its npm package is unmaintained; enthec/webappanalyzer (GPL-3.0) is where the data lives now. The snapshot is refreshed when the Actor is rebuilt.
Is it a BuiltWith alternative? For looking up the stack of websites you already have, yes, and it checks each site live rather than reading a stored profile. It does not do BuiltWith's other jobs: there is no historical data and no reverse lookup ("find all sites that use Shopify"). Bring the list of domains; the Actor tells you what each one runs today.
Does it need an account or an API key anywhere? No. It fetches public pages with no login of any kind, and it calls no third-party detection API.
Is it legal to detect a website's technology stack? The Actor requests public pages the way a browser does and reads only what the server chooses to send. It does not log in, does not bypass any access control and does not collect personal data. You are responsible for the list of URLs you supply and for how you use the results.
Do I need proxies? Usually not. You are fetching your own list of URLs, so there is no anti-bot surface. Turn on Apify Proxy datacenter groups only if a site refuses the platform's own IP range.
Can I upload a CSV or a Google Sheet of URLs?
Yes. In Websites to analyse, upload a file or paste a Google Sheet link, or send
{ "requestsFromUrl": "<link>" } in startUrls through the API. Supported formats:
- a plain text file with one URL or domain per line;
- a CSV, comma, semicolon or tab separated, quoted or not. If the first row is a header naming a
url,websiteordomaincolumn, only that column is read, so LinkedIn or logo links elsewhere in the row are not analysed or billed. Without such a header, every cell holding a URL or domain is read; - a Google Sheet, shared as "Anyone with the link can view". The tab the link points at is the one read.
Excel files are not read; save the sheet as CSV first. Duplicates across all lists and typed URLs are removed,
and maxItems still caps the total. A list that cannot be downloaded is skipped with a warning in the log.
Why did it miss React (or Vue, or Angular) on a site I know uses it? Those frameworks are often detected by a variable in the running page, which needs a browser. This Actor is HTTP-only by design, because that is what makes it fast and cheap. When a framework leaves a trace in the markup or the script URLs it is found; a fully client-rendered app with a generic bundle name may not be.
Why is a technology listed that the site does not obviously use? Check the evidence. Some fingerprints match a vendor named in a Content-Security-Policy header, which proves the site allows the vendor rather than that it currently loads it. Those rows say
"type": "header", "key": "content-security-policy"What does confidence mean? It is the fingerprint author's weighting, not a probability. A single weak pattern scores 40 or 50, several independent patterns add up, and the total caps at 100.
Why is version usually null?
Only some fingerprints capture a version, and only when the site exposes one, typically in a ?ver= query string,
a meta generator tag or a server header. Most sites strip those.
Does it crawl the site? No. One request per URL you supply, plus its script files. For several pages of one site, put several URLs in the input.
Found a bug, or need something else? Open an issue on the Issues tab and it will be picked up. If you need a fingerprint that is missing, or a browser-based mode that reads JavaScript globals, say so in the issue.