Website Tech Stack Detector: CMS, Frameworks & Hosting
Pricing
$1.20 / 1,000 website analyseds
Website Tech Stack Detector: CMS, Frameworks & Hosting
Find the CMS, ecommerce platform, frameworks, analytics, hosting, CDN, email provider and 6,700+ other technologies behind any list of websites. One row per site, with versions and evidence.
Pricing
$1.20 / 1,000 website analyseds
Rating
0.0
(0)
Developer
vantum
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Security
Limited permissionsShare
Website Tech Stack Detector
Paste a list of websites and get one row per site listing what it runs on:
- CMS and ecommerce platform, e.g. WordPress 7.2, Shopify, Magento, Wix, Webflow or Squarespace;
- frameworks and libraries, e.g. Next.js, Nuxt, React, Vue, Angular, Astro, SvelteKit, jQuery 3.7.1 or Bootstrap 5.3.2;
- marketing and sales tools: analytics, tag managers, ad pixels, marketing automation, CRM, live chat, A/B testing, reviews, cookie consent and payments;
- infrastructure: hosting and PaaS, CDN, web server, reverse proxy, language, caching, security/WAF and the TLS certificate issuer and expiry;
- email setup from DNS: email provider (Google Workspace, Microsoft 365…), sending services in SPF (SendGrid, Mailchimp, HubSpot, Zendesk…), domain verifications (which SaaS tools the company verified) and nameservers;
- company details: page title, description, language, social profiles (LinkedIn, X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest) and
mailto:emails.
Each technology comes with its version when the site exposes it, a confidence score, its categories, its CPE (for security teams), the evidence that matched and which technology implied it.
Detection uses the open-source webappanalyzer fingerprint set: 7,600+ technologies in the format popularised by Wappalyzer, pinned to a known commit. It runs over plain HTTP and DNS with no browser, so it is fast. $1.20 per 1,000 websites. Sites that fail, block the request or are not HTML pages are free, and so are dry runs.
Why this one
| This Actor | Typical tech-stack actors | |
|---|---|---|
| Price | $0.0012 per website, no start fee | $0.0015–$0.10 per website, often plus a start fee |
| Failed, blocked and non-HTML sites | free | often charged as a result row |
| Fingerprints | 7,600+, pinned open-source set, named in every run | varies, often undisclosed or an old snapshot |
| Version numbers and confidence | ✅ | some |
| Evidence for every match (header, script URL, meta tag, DOM element, cookie, DNS record) | ✅ | ❌ |
implies / requires / excludes rules (e.g. WooCommerce only with WordPress) | ✅ | rarely |
| Email provider, SPF senders, domain verifications from DNS | ✅ free | ❌ or a separate actor |
| TLS issuer and expiry date | ✅ | ❌ |
| Social profiles and emails | ✅ | some |
| Flat columns per category (CMS, analytics, hosting…) for CSV/Excel | ✅ 30 columns | some |
| Change tracking between scheduled runs (added / removed technologies) | ✅ | ❌ |
| Free dry run (validate, de-duplicate, maximum cost) | ✅ | ❌ |
| Bulk input: bare domains, URLs, uploaded files, duplicates removed | ✅ | partial |
Quick start
- Paste websites, one per line (Bulk edit for long lists):
example.com,www.example.comorhttps://example.com/shopall work. - Run. Open the Overview, Marketing & sales stack, Infrastructure or Company & contacts tab, or download all rows as CSV, Excel or JSON.
{"websites": ["https://wordpress.org/news/", "nextjs.org", "books.toscrape.com"],"checkDns": true,"minConfidence": 50}
From the API, startUrls: [{ "url": "https://a.com" }], urls and domains are accepted too.
Use cases
- Lead generation: find every Shopify store, or every site on HubSpot, in a list of prospects. Filter the CSV by the
ecommerce,crmormarketingAutomationcolumn. - Sales intelligence: know a prospect's stack before the call: CMS, analytics, chat, payments, email provider.
- Competitor monitoring: schedule a weekly run with Track changes and get a
changesfield when a competitor adds or drops a tool. - Security and IT inventory: versions plus CPE identifiers for the web-facing software of many domains, and certificate expiry dates.
- Market research:
RUN_SUMMARYlists the 50 most common technologies across your list.
How it works
- For each website it fetches the URL you gave, usually the home page, following up to 10 redirects. With no
https://given it tries HTTPS first, then HTTP if HTTPS cannot connect. - At the same time it reads the domain's DNS records (MX, TXT, NS, SOA, CNAME). DNS is checked on the host you gave without
www.. - It matches the response headers, cookies, HTML, script URLs, inline scripts and styles, meta tags, DOM elements, visible text, DNS records and the TLS certificate issuer against the fingerprints. Then it applies the fingerprints'
implies,requiresandexcludesrules. Versions come from the matched values; when several are found, the highest is reported. - A browser would also see JavaScript globals. Instead, a global counts as present when an inline script assigns it (
window.X =,var X =). A small supplement adds the static markers of server-rendered frameworks (for example__NEXT_DATA__and/_next/static/for Next.js,/_astro/for Astro,/_app/immutable/for SvelteKit). The upstream file is never changed. - Hints the fingerprint set marks with confidence 0 are dropped. Minimum confidence (default 50) hides weak single hints.
- Up to Max concurrency websites (default 10) run in parallel. Each is a different server and gets only one or two requests.
- If the run is about to time out, it stops starting new websites and still writes the summary. After a platform migration it resumes without re-checking, or re-charging, finished websites.
Statuses (only ok is charged)
status | Meaning | Charged |
|---|---|---|
ok | Page fetched (HTTP < 400, HTML) and analysed | ✅ $0.0012 |
blocked | 401/403/429 or a bot challenge page (Cloudflare, DataDome, Akamai…) | free |
httpError | Other HTTP error (404, 500…) | free |
notHtml | The URL is a PDF, image, JSON… | free |
failed | DNS error, timeout, TLS error, connection refused, redirect loop | free |
dryRun | Dry run row | free |
Free rows still include whatever the headers, TLS certificate and DNS revealed, for example Cloudflare, the email provider or the hosting.
Output
One dataset row per website. Abridged example (real output from wordpress.org):
{"url": "https://wordpress.org/news/","domain": "wordpress.org","status": "ok","statusCode": 200,"title": "WordPress News – The latest news about WordPress and the WordPress community","language": "en-US","technologyCount": 14,"technologies": [{"name": "WordPress", "version": "7.2", "confidence": 100, "categories": ["CMS", "Blogs"],"website": "https://wordpress.org", "cpe": "cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*","evidence": ["html: <link rel='stylesheet' id='wp-block-navigation-css' href='https://wordpress.org/news/wp-includes/","header link: <https://wordpress.org/news/wp-json/>; rel=\"https://api.w.org/\""],"impliedBy": null},{ "name": "PHP", "version": null, "confidence": 100, "categories": ["Programming languages"], "impliedBy": ["WordPress"] },{ "name": "Google Tag Manager", "confidence": 100, "evidence": ["html: googletagmanager.com/ns.html?id=GTM-…"] }],"cms": ["WordPress 7.2"],"pageBuilders": ["WordPress Block Editor", "WordPress Site Editor"],"tagManagers": ["Google Tag Manager"],"webServers": ["Nginx"],"programmingLanguages": ["PHP"],"databases": ["MySQL"],"mxRecords": ["smtp1-dca.wordpress.org", "smtp2-dca.wordpress.org"],"spfSenders": ["Help Scout"],"domainVerifications": ["google"],"tlsIssuer": "Let's Encrypt","tlsExpires": "2026-12-22","socialProfiles": { "x": "https://www.x.com/WordPress", "linkedin": "https://www.linkedin.com/company/wordpress" },"charged": true,"checkedAt": "2026-10-31T19:57:04Z"}
A Shopify store from the same test run (www.allbirds.com) came back with ecommerce: ["Shopify"], payments: ["Apple Pay", "PayPal", "Shop Pay"], cdn: ["Cloudflare"], emailProvider: "Microsoft 365" and evidence such as script: https://cdn.shopify.com/… and inline script sets ShopifyAnalytics.
Flat category columns (array of names, with version when known, or null): cms, ecommerce, blogs, pageBuilders, staticSiteGenerators, jsFrameworks, webFrameworks, jsLibraries, uiFrameworks, analytics, tagManagers, advertising, retargeting, marketingAutomation, crm, liveChat, payments, abTesting, cookieConsent, reviews, cdn, hosting, webServers, reverseProxies, programmingLanguages, databases, security, caching, fonts, sslCertificateAuthority. Every technology is in technologies, including categories without a flat column.
DNS fields (with Check DNS): emailProvider, emailProviders, mxRecords, spfSenders, spf, domainVerifications, nameservers.
Other fields: finalUrl, error, description, generator, tlsIssuer, tlsExpires, redirects, socialProfiles, emails, responseTimeMs, changes (with change tracking) and charged.
The RUN_SUMMARY record holds counts by status, charged websites, the 50 most common technologies, skipped inputs and the fingerprint commit used.
Change tracking
Turn on Track changes and schedule the Actor. Each website's technology list is saved in a named key-value store (tech-stack-history by default; it persists between runs). Each ok row then gets:
"changes": { "added": ["Klaviyo"], "removed": ["Mailchimp"], "changed": true, "previousCheckAt": "2026-10-24T06:00:02Z" }
The first check of a website has "firstCheck": true. Use a different History store name for each watch list. Changes compare technologies at or above your minimum confidence, so keep that setting the same between runs.
Input
| Field | Default | Description |
|---|---|---|
websites | – | Websites or domains, one per line (also startUrls, urls or domains via API). Up to 100,000 per run. |
checkDns | true | Read MX/TXT/NS/SOA/CNAME for the email provider, SPF senders, verifications and DNS-detected technologies. |
minConfidence | 50 | Hide technologies below this confidence (1–100). |
includeEvidence | true | Add evidence and impliedBy to each technology. |
includeContacts | true | Add social profiles and mailto: emails. |
trackChanges | false | Add changes versus the previous run. |
historyStoreName | tech-stack-history | Named store used by change tracking. |
dryRun | false | Validate and de-duplicate the list and report the maximum cost. Visits nothing and charges nothing. |
maxConcurrency | 10 | Websites checked in parallel (1–50). |
requestTimeoutSecs | 25 | Per-website timeout. |
userAgent | Chrome desktop | Custom User-Agent. |
Pricing
Pay per event: $0.0012 per analysed website ($1.20 per 1,000). No start fee and no monthly rental. Blocked, failed, HTTP-error and non-HTML websites are free, and so are dry runs and DNS lookups. Set a maximum cost per run in the run options: the Actor stops cleanly when it reaches it.
Limitations
- One page per website. It checks the page you give, usually the home page. Tools used only on other pages (for example a checkout provider) are found only if you give that page's URL.
- No browser. Technologies that are visible only after JavaScript runs, and add no markers to the HTML, headers or DNS, are not detected. Those are about 900 of the 7,600 fingerprints, mostly ones keyed only on runtime globals; the inline-script heuristic recovers some of them.
- Sites behind aggressive bot protection may return
blocked. Those rows are free and still show what the headers and DNS reveal. - Like every fingerprint-based detector, results are evidence-based guesses. Check the
evidencefield when a match matters.
Fingerprint data and license
Technology fingerprints come from enthec/webappanalyzer, licensed GPL-3.0. They are downloaded unmodified at a pinned commit when the Actor is built, and the license is included in the image (data/LICENSE-webappanalyzer-GPL-3.0.txt). The RUN_SUMMARY record names the commit used. The detection engine, the static-marker supplement and the email-provider mapping are this Actor's own. This Actor is not affiliated with Wappalyzer, BuiltWith or enthec.
FAQ
Is this the same as Wappalyzer? It uses the same open fingerprint format and an actively maintained community fork of that dataset, but it is an independent engine. Wappalyzer's browser extension also sees runtime JavaScript; this Actor trades that for speed and price.
Can I check thousands of domains? Yes: paste them with Bulk edit or send them via the API. In the test run, 6 websites took 2.5 seconds in total at the default concurrency of 10.
Why does a site show blocked? It refused automated requests. You are not charged. Try again later or with a lower concurrency.
Does it store anything in my account? Only the dataset and RUN_SUMMARY for each run, plus the named history store if you turn on change tracking.