How to Detect What JavaScript Framework a Website Uses
Whether you're evaluating a competitor's tech choices, planning a migration, assessing security exposure, or researching hiring needs, knowing which JavaScript framework powers a website is valuable information. React, Vue, Angular, Next.js, Nuxt, and Svelte each leave distinct fingerprints in the DOM, in JavaScript globals, and in HTTP responses—if you know where to look.
This guide covers three approaches: manual detection with browser DevTools, browser extensions like Wappalyzer, and programmatic detection with the DetectZeStack API. Each has trade-offs in accuracy, scalability, and what they can actually see.
Why Framework Detection Matters
Identifying the JavaScript framework behind a website isn't just trivia. There are concrete reasons teams care about this:
- Competitive analysis: Understanding what frameworks competitors chose (and when they switched) reveals their engineering priorities and constraints.
- Security auditing: Specific framework versions have known CVEs. Detecting Angular 1.x or an outdated React version is a concrete security finding.
- Hiring and team planning: If a company you're joining (or acquiring) runs Next.js, you need Next.js engineers. The framework choice shapes the entire hiring pipeline.
- Migration planning: Before migrating from Angular to React or from Vue 2 to Vue 3, you need to know exactly what's running in production—not what the internal wiki says.
- Sales prospecting: If you sell developer tools, knowing that a company uses React vs. Angular determines whether your product is relevant to them. The same logic applies to detecting WordPress sites or distinguishing Shopify from WooCommerce for e-commerce-focused outreach.
How JavaScript Frameworks Leave Fingerprints
Every major framework leaves identifiable traces in the rendered page. Some are intentional (development aids), others are side effects of how the framework renders HTML. Here are the signatures for the most popular frameworks:
React
__REACT_DEVTOOLS_GLOBAL_HOOK__on thewindowobject (injected by React DevTools, but React itself checks for it)data-reactrootattribute on the root DOM element (React 16+)data-reactidattributes on elements (React 15 and earlier)_reactRootContainerproperty on the root DOM node- Bundled JS files often contain
react-domorreact.production.minin their paths or source
Vue.js
__VUE__global variable (Vue 3)__vue__property on DOM elements mounted by Vue 2data-v-scoped style attributes on HTML elements (Vue's scoped CSS adds unique hashes likedata-v-2fc2a9f2)Vueconstructor on thewindowobject in development builds
Angular
ng-versionattribute on the root element (e.g.,ng-version="17.2.1")—this is the most reliable signal and includes the exact version number_nghost-and_ngcontent-attributes on elements (Angular's view encapsulation)ng-prefixed attributes throughout the DOM (ng-reflect-,ng-star-inserted)- AngularJS (1.x) uses
ng-app,ng-controller,ng-modeldirectives directly in HTML
Next.js
__NEXT_DATA__script tag containing a JSON object with page props, build ID, and route informationX-Nextjs-CacheHTTP response header (when using ISR or SSG)/_next/path prefix for static assets and chunks__nextas the root div ID
Nuxt
__NUXT__global variable containing server-rendered state_nuxtas a root div ID or class/_nuxt/path prefix for bundled assets- Nuxt 3 uses
__nuxt(double underscore) as the app container ID
Svelte
- Svelte compiles away at build time, leaving minimal runtime traces
- Elements may have
class="svelte-prefixed CSS classes (e.g.,svelte-1a2b3c4) - SvelteKit uses
__sveltekit_globals anddata-sveltekit-attributes - No virtual DOM or framework runtime in the bundle—Svelte is the hardest framework to detect automatically
Manual Detection with Browser DevTools
You can identify most frameworks in under 30 seconds using Chrome DevTools. Here are three techniques:
1. Check the DOM (Elements tab)
Open DevTools (F12), go to the Elements tab, and inspect the root <div> or <body> element. Look for:
ng-version="X.Y.Z"— Angular, with the exact versiondata-reactroot— Reactid="__next"— Next.jsid="__nuxt"orid="_nuxt"— Nuxtdata-v-attributes on elements — Vue
2. Check window globals (Console tab)
Open the Console tab and type these one at a time:
// React
!!document.querySelector('[data-reactroot]') || !!document.querySelector('#__next')
// Vue
!!window.__VUE__ || !!document.querySelector('[data-v-]')
// Angular
!!document.querySelector('[ng-version]')
// Next.js
!!window.__NEXT_DATA__
// Nuxt
!!window.__NUXT__
Each returns true or false. The ng-version attribute is especially useful because it gives you the exact Angular version: document.querySelector('[ng-version]')?.getAttribute('ng-version').
3. Check the Network tab
Reload the page with the Network tab open and filter by JS files. Look for telltale paths:
/_next/static/chunks/— Next.js/_nuxt/— Nuxt- Files named
vendor.jsormain.jscontainingreact-dom,vue, or@angular/corein their source
Also check response headers: an X-Nextjs-Cache header confirms Next.js, while X-Powered-By: Nuxt confirms Nuxt (though many sites strip the X-Powered-By header for security).
Using Browser Extensions
Extensions like Wappalyzer, WhatRuns, and the BuiltWith browser addon automate the DOM and header checks described above. They run JavaScript on each page you visit and match patterns against a database of technology signatures. For a full comparison of these tools (including free options), see our free BuiltWith alternatives guide.
What they do well
- Detect major frameworks (React, Vue, Angular) reliably on client-rendered pages
- Identify meta-frameworks (Next.js, Nuxt, Gatsby) through their distinctive DOM patterns
- Show results instantly with no setup—just install and browse
- Often detect version numbers when they're exposed in the DOM
What they miss
- Server-side only frameworks: If a site server-renders with Next.js but strips
__NEXT_DATA__or serves fully static HTML, extensions may miss it - Infrastructure layer: Extensions can't inspect DNS records or TLS certificates, so they miss CDN providers, hosting platforms, and certificate authorities. See why DNS and TLS detection matters for details on what's invisible to extensions.
- Minified and obfuscated bundles: When framework identifiers are tree-shaken or renamed by bundlers, pattern matching may fail
- Scale: Extensions work one page at a time. You can't scan 1,000 competitor sites through a browser extension.
Programmatic Detection with the DetectZeStack API
For anything beyond one-off manual checks—competitive research across dozens of sites, security audits, or building detection into your own tools—you need an API. If you're building AI-powered workflows, you can also integrate tech detection into AI agents via MCP. DetectZeStack's /analyze endpoint fetches the target URL, inspects the HTML, HTTP headers, JavaScript, DNS records, and TLS certificates, then returns structured JSON.
curl -s "https://detectzestack.p.rapidapi.com/analyze?url=vercel.com" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" | jq '.technologies[] | {name, categories, version}'
A response for a Next.js site typically includes:
{
"name": "Next.js",
"categories": ["Static site generator", "JavaScript frameworks"],
"version": null
}
{
"name": "React",
"categories": ["JavaScript frameworks"],
"version": null
}
{
"name": "Vercel",
"categories": ["PaaS"],
"version": null
}
{
"name": "Node.js",
"categories": ["Programming languages"],
"version": null
}
Notice that the API detects the full stack: Next.js (the meta-framework), React (the underlying library), Vercel (the hosting platform via DNS), and Node.js (the runtime). A browser extension would catch Next.js and React but miss Vercel and Node.js.
For scanning multiple sites at once, the batch endpoint accepts up to 10 URLs in a single request, making competitive analysis straightforward.
SSR Frameworks Are Harder to Detect
Server-side rendering (SSR) complicates detection because the server may deliver fully rendered HTML without exposing client-side framework globals. Here's how SSR affects detection for each framework:
Next.js
Next.js is usually detectable even with SSR because it embeds a <script id="__NEXT_DATA__"> tag containing the page props and build ID. ISR (Incremental Static Regeneration) pages also expose the X-Nextjs-Cache response header. However, if a site uses Next.js only for the build step and exports purely static HTML, these signals disappear.
Nuxt
Nuxt SSR pages include the __NUXT__ global with serialized server state. Nuxt 3 also sets a __nuxt root element. Static-generated Nuxt sites (nuxt generate) may retain these markers, but heavily customized deployments can strip them.
Angular Universal
Angular's SSR solution (Angular Universal) still renders the ng-version attribute on the root element, making server-rendered Angular pages as detectable as client-rendered ones. This is one of the most reliable framework fingerprints across any rendering mode.
SvelteKit
SvelteKit SSR pages leave fewer traces than other frameworks because Svelte compiles components to vanilla JavaScript at build time. The resulting HTML may contain svelte- prefixed CSS classes, but there's no runtime global to check. This makes Svelte and SvelteKit the hardest major frameworks to detect programmatically.
When Frameworks Hide
Several factors can make framework detection unreliable, regardless of which method you use:
- Bundler minification: Webpack, Vite, and esbuild can rename or remove framework identifiers during production builds. Tree-shaking may eliminate unused code paths that would otherwise serve as fingerprints.
- CDN caching: Some CDN configurations strip custom HTTP headers (like
X-Powered-ByorX-Nextjs-Cache) before delivering responses to clients. If you're relying on headers, the CDN layer can hide them. DNS-based detection can still identify the CDN and hosting provider even when headers are stripped. - Security hardening: Security-conscious teams deliberately remove framework version information. Stripping
X-Powered-Byheaders and removing__NEXT_DATA__reduces information leakage that could help attackers target known vulnerabilities. - Micro-frontends: Sites using module federation or micro-frontend architectures may run multiple frameworks simultaneously. Detection tools might report React and Vue on the same page—and both results could be correct.
- Custom renderers: Some organizations build custom server-side rendering pipelines that use React or Vue internally but produce clean HTML without framework-specific attributes.
Tip: When a single detection method fails, combining approaches works better. The DetectZeStack API already does this—it cross-references HTML patterns, HTTP headers, JavaScript globals, DNS records, and TLS certificates to maximize detection accuracy.
Detection Methods Compared
| Criteria | Manual (DevTools) | Browser Extension | API (DetectZeStack) |
|---|---|---|---|
| Setup required | None | Install extension | API key (free) |
| Speed per site | 30–60 seconds | Instant (page load) | 1–3 seconds |
| Bulk scanning | No | No | Yes (batch endpoint) |
| Detects React/Vue/Angular | Yes | Yes | Yes |
| Detects Next.js/Nuxt | Yes | Yes | Yes |
| Detects Svelte/SvelteKit | Sometimes | Sometimes | Sometimes |
| CDN/hosting detection | No | No | Yes (DNS + TLS) |
| Version detection | Yes (if exposed) | Yes (if exposed) | Yes (if exposed) |
| Automation/CI integration | No | No | Yes (REST API) |
| Cost | Free | Free (basic) | Free (100 req/mo) |
Manual inspection is the most thorough for a single site—you can dig into minified bundles, explore the DOM tree, and check every header. But it doesn't scale. Browser extensions automate the process for casual use. The API is the only option that supports bulk scanning, CI integration, and infrastructure-layer detection via DNS and TLS.
Practical Recommendations
One-off check
Open DevTools, check the DOM root for ng-version, data-reactroot, or __next. Check the Console for __NEXT_DATA__ or __NUXT__. Takes 30 seconds.
Browsing competitors
Install the Wappalyzer extension. It identifies frameworks on every page you visit with zero effort. Good for passive discovery.
Systematic research
Use the DetectZeStack API to scan dozens or hundreds of sites programmatically. The batch endpoint handles up to 10 URLs per request, and you get infrastructure data that extensions miss.
Related Reading
- Browser Extensions Miss Your Infrastructure Layer — Why DNS and TLS detection matters
- Detect Any Website's Tech Stack with a Single API Call — Getting started with the API
- Website Technology Detection: Python Tutorial — Batch scanning with Python
- Website Technology Checker API — Full endpoint reference
- BuiltWith vs Wappalyzer vs DetectZeStack — Full tool comparison
- How to Check if a Website Uses WordPress — CMS detection guide
- Shopify vs WooCommerce Detection — Identify e-commerce platforms
- Free BuiltWith Alternatives (2026) — Compare tech detection tools
- Tech Stack Detection with MCP and AI Agents — AI-powered automation
- How to Detect CDN and Hosting Provider — Infrastructure-layer detection
Try DetectZeStack Free
100 requests/month, no credit card required. Detect JavaScript frameworks, infrastructure, and more in a single API call.
Get Your API Key