First CH Apps / Tech Stack Detector
Enter a URL and we infer the CMS, commerce platform, framework, CDN, analytics tags and web fonts behind it from the page's HTML and response headers. We never give you a bare verdict — every detection comes with the evidence that produced it. It is built for taking stock of a site you have inherited or tidying up your own tags, not for profiling other people's sites.
Grading the safety of headers belongs to the Security Header Grader, certificates to the SSL/TLS Certificate Checker, and title/description to the Meta Tag & SEO Basics Check. This page answers one question: what is this site built with?
The top page is usually enough. CMS fingerprints sometimes only appear on deeper pages, so try an article or product page if the result looks thin.
These are inferences, not facts. "Confirmed" means a signature that only that technology produces (a header, cookie name or asset host); "Likely" means several supporting hints lined up; "Possible" means a single hint. "Inferred" means a technology the detected one depends on (Next.js → React) — we saw no fingerprint of it directly.
Not detected does not mean not used. A CDN such as Cloudflare in front of the origin erases almost everything about the server behind it, and plenty of technologies (Tailwind CSS, React) leave no trace after a build.
Web servers (nginx, Apache, IIS) cannot be identified at all. This app runs on Cloudflare Workers, and the runtime rewrites the Server header of every response it fetches to its own name, cloudflare (measured in production on 2026-09-18). Rather than report nginx from a value we know to be forged, we tell you it is invisible. Cloudflare itself is therefore detected only from traces the runtime does not touch: the NEL reporting endpoint, the __cf_bm cookie and /cdn-cgi/ paths.
Tags injected after JavaScript runs — anything fired through a tag manager, for instance — are invisible server-side. If GTM is detected, what runs inside it is not something this page can tell you.
We look at the single page you enter. Within one site the top page may be statically exported while another section runs a CMS.
A product name written in the page text never triggers a detection (comparison articles list every vendor). We only match strings that a technology cannot avoid emitting: asset hostnames, cookie names and headers.
The ledger holds signatures for 78 technologies (last updated 2026-09-18). It is plain JSON, kept apart from the code so it can grow by appending.
Six places are inspected: response headers (only those the ledger names), Set-Cookie names, meta tags, script src, link href, and the HTML body plus the final URL. The Server header and cf-ray are never used, because our runtime replaces them.
Each signature carries a weight of 0–100. A total of 100 reads as Confirmed, 50 or more as Likely, below 50 as Possible (the total is capped at 100).
Versions are shown only where the software announces itself (a meta generator or Server header) — we never guess them. Remember that a version you can see here is equally visible to an attacker.
Only the first 256KB of HTML is scanned, to stay inside the free-tier CPU limit.
Only cookie names are used. Values (session IDs and the like) are never read and never returned.
Sent: only the URL you type. Our server (Cloudflare Workers) fetches it once with a public GET. No cookies and no credentials are sent, and we never request the URLs found inside the page (CDNs, tags, fonts).
Stored: nothing. Detection lives entirely inside one request and writes neither the URL nor the result to any database (no KV, no D1). It leaves memory when the request ends.
Returned: the technology names, our verdicts and **only the matched strings** (up to 120 characters each). Neither the fetched page nor a dump of its response headers is re-served — this app cannot be used to browse other sites through us.
Cookies: only Set-Cookie names feed the detection; values are never touched. We fetch a public page exactly as an anonymous visitor would, so no one's session is involved.
Note: public GET only. URLs pointing at internal networks, localhost or private IPs are rejected.
POST /tech-detect/api/detect with JSON ({"url": "https://example.com/"}) or a form body and you get the same result back as JSON.