How to Detect React Version on Any Website Programmatically
React powers roughly 40% of all websites that use a JavaScript framework. But not all React is created equal. A site running React 16 has a fundamentally different architecture than one running React 19 with Server Components. If you need to know what React version a website is using — for competitive analysis, security auditing, migration planning, or lead generation — you need a reliable, programmatic way to detect it.
This guide walks through every method for detecting React versions on websites: manual browser techniques, their limitations, and the API approach that lets you check React version on any site at scale. You will walk away with working code in curl, Node.js, and Python.
Why Detect React Version on a Website?
Knowing which version of React a site runs is more than a trivia exercise. It unlocks concrete business decisions across several workflows:
- Security auditing: React 16.x and earlier have known XSS-related CVEs. React 17 changed the event delegation model for security reasons. React 18 introduced stricter hydration checks. If you are auditing a portfolio of web properties — your own or a client's — knowing the React version tells you which vulnerabilities apply and what upgrade path is needed.
- Competitive analysis: Tracking whether competitors upgrade to React 19 (Server Components, Actions, use() hook) reveals their engineering investment priorities. A company still on React 16 is likely dealing with legacy constraints. A company on React 19 is investing heavily in frontend architecture.
- Migration planning: If you are a consultancy that helps companies upgrade React, the version number is the first thing you need. React 16 to 18 is a different migration than React 17 to 19. The version determines the scope, cost, and risk of the project. Detecting versions at scale lets you build qualified prospect lists.
- M&A due diligence: Technical due diligence during acquisitions requires understanding the target's technology stack. Running React 15 with class components signals years of accumulated technical debt. Running React 19 with modern patterns signals an actively maintained codebase. The version number is a proxy for engineering health.
- Lead generation for React tooling: If you sell React component libraries, testing tools, performance monitoring, or state management solutions, you need to know which sites run React and which version they use. A site on React 18 is a potential buyer for concurrent rendering tools. A site on React 16 needs migration services first.
The common thread: you need to check many websites, not just one. Manual methods break down fast when you are scanning hundreds or thousands of URLs. Let's examine them anyway, because understanding the detection signals makes the API solution clearer.
Manual Methods for Detecting React Version
Before reaching for an API, here are the signals that indicate React is present and which version is running. These are the same signals that detection tools use under the hood.
1. React DevTools browser extension
The most common manual method is installing the React Developer Tools browser extension. When you visit a React-powered site, the extension icon lights up and shows the React version in its panel. Open Chrome DevTools, navigate to the "Components" tab, and the version appears in the header.
This works well for a single site, but it requires a browser, a human, and clicking through each site one at a time. It cannot be automated and it cannot be run headlessly at scale.
2. The __REACT_DEVTOOLS_GLOBAL_HOOK__ object
Even without the DevTools extension installed, you can access React's internal hook in the browser console. Open DevTools on any React site and run:
// Check if React is present
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
const renderers = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers;
renderers.forEach(function(renderer) {
console.log('React version:', renderer.version);
});
}
The renderers Map contains each React renderer (typically ReactDOM) along with its version string. This is reliable when it works, but it requires JavaScript execution in a browser context — a simple HTTP request to fetch the page source will not expose this object.
3. Check for data-reactroot and data-reactid attributes
Older React versions (15 and earlier) inject data-reactid attributes on every DOM element they manage. React 16+ replaced this with a single data-reactroot attribute on the root container. You can check the page source for these attributes:
curl -s "https://example.com" | grep -c "data-reactroot"
# Count > 0 suggests React 16+
curl -s "https://example.com" | grep -c "data-reactid"
# Count > 0 suggests React 15 or earlier
This gives you a rough era of React but not the specific version number. It also fails on server-rendered React apps that may strip these attributes during hydration.
4. Search bundled JavaScript for version strings
React includes version strings in its production bundle. If you can find the bundled React file (often named something like react.production.min.js, react-dom.production.min.js, or a hashed chunk file), you can search for the version pattern:
curl -s "https://example.com" | grep -oP 'react\.production\.min\.js'
# Find the React bundle URL, then:
curl -s "https://example.com/static/js/react.production.min.js" | \
grep -oP '["\x27](\d+\.\d+\.\d+)["\x27]' | head -1
The version is typically embedded as a string literal in the minified bundle. However, modern bundlers like webpack, Vite, and Turbopack often split and rename chunks, making it difficult to locate the React bundle reliably. Tree-shaking and code splitting can scatter version references across multiple files.
5. Check for React-specific HTTP headers and meta tags
Some React meta-frameworks add their own fingerprints. Next.js adds x-powered-by: Next.js headers and __NEXT_DATA__ script tags. Gatsby adds ___gatsby div IDs. Remix adds specific meta tags. These do not tell you the React version directly, but they narrow down the React ecosystem the site operates in, which correlates with version ranges.
curl -sI "https://example.com" | grep -i "x-powered-by"
# "Next.js" implies React 18+ in most cases (Next.js 13+ requires React 18)
The Problem with Manual React Version Detection
Each method above works for a single website if you are willing to spend a few minutes poking around. But they all share fundamental scaling problems:
- No single signal is reliable. Some sites strip
data-reactrootattributes. Some use custom builds that remove version strings. Some serve different bundles to different user agents. You need to check multiple signals and combine them for accurate detection. - JavaScript execution is often required. The most reliable method (
__REACT_DEVTOOLS_GLOBAL_HOOK__) requires a full browser environment. Running headless Chrome at scale is expensive, slow, and fragile. You are spinning up entire browser instances just to read a version string. - Modern bundling obscures everything. Webpack chunk hashing, dynamic imports, CDN-rewritten URLs, and code splitting make it nearly impossible to reliably locate the React bundle from the HTML source alone. What worked on one site will fail on the next.
- Version detection is harder than presence detection. Knowing a site uses React is relatively easy (check for
data-reactrootor_reactRootContainer). Knowing the exact version requires finding the version string in minified JavaScript, which is a significantly harder problem at scale. - Rate limits and bot protection. Many React-powered sites use Cloudflare, Akamai, or Vercel's bot protection. Automated scraping to find version strings will get you blocked quickly. Purpose-built APIs handle this infrastructure problem for you.
This is exactly why a React version detection API exists. It combines all of these detection signals, handles edge cases, runs the JavaScript when needed, and returns a clean JSON response with the version number.
The StackPeek API: Detect React Version with One GET Request
The StackPeek API detects 120+ technologies — including React and its version — from a single HTTP request. No headless browser on your end. No scraping. No maintaining your own fingerprint database. You send a URL, you get back a JSON response with every detected technology, version numbers, and confidence scores.
Here's how it works.
curl
curl "https://stackpeek.web.app/api/v1/scan?url=vercel.com"
Response:
{
"url": "vercel.com",
"technologies": [
{
"name": "React",
"category": "JavaScript Framework",
"version": "19.0.0",
"confidence": 0.98
},
{
"name": "Next.js",
"category": "Web Framework",
"version": "15.2.0",
"confidence": 0.99
},
{
"name": "Vercel",
"category": "Hosting",
"confidence": 0.99
}
],
"scanTime": "387ms"
}
One request. React version, framework, hosting — all in structured JSON with confidence scores. Under 500 milliseconds. No API key required for the free tier (100 scans per day).
Node.js
const url = "vercel.com";
const response = await fetch(
`https://stackpeek.web.app/api/v1/scan?url=${encodeURIComponent(url)}`
);
const data = await response.json();
const react = data.technologies.find(
t => t.name.toLowerCase() === 'react'
);
if (react) {
console.log(`React ${react.version || 'unknown version'} detected`);
console.log(`Confidence: ${(react.confidence * 100).toFixed(0)}%`);
} else {
console.log('React not detected on this site');
}
Python
import requests
url = "vercel.com"
resp = requests.get(
f"https://stackpeek.web.app/api/v1/scan?url={url}"
)
data = resp.json()
react = next(
(t for t in data["technologies"]
if t["name"].lower() == "react"),
None
)
if react:
version = react.get("version", "unknown")
print(f"React {version} detected ({react['confidence']:.0%} confidence)")
else:
print("React not detected")
Batch Scanning: Check React Versions Across Thousands of Sites
Checking a single site is useful for curiosity. The real value comes when you scan an entire list of URLs and build a dataset of React versions. Here's a complete Python script that reads URLs from a file, scans each one, and outputs a CSV with the React version for every site that uses it:
import requests
import csv
import time
API_BASE = "https://stackpeek.web.app/api/v1/scan"
def get_react_version(url):
"""Returns (version, confidence) or (None, None) if React not found."""
try:
resp = requests.get(f"{API_BASE}?url={url}", timeout=15)
data = resp.json()
react = next(
(t for t in data.get("technologies", [])
if t["name"].lower() == "react"),
None
)
if react:
return react.get("version", "detected"), react["confidence"]
return None, None
except Exception:
return None, None
# Read URLs
with open("urls.txt") as f:
urls = [line.strip() for line in f if line.strip()]
# Scan and collect results
results = []
for i, url in enumerate(urls):
print(f"Scanning {i+1}/{len(urls)}: {url}")
version, confidence = get_react_version(url)
if version:
results.append({"url": url, "version": version, "confidence": confidence})
print(f" -> React {version} ({confidence:.0%})")
time.sleep(0.2) # respect rate limits
# Write CSV
with open("react_versions.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["url", "version", "confidence"])
writer.writeheader()
writer.writerows(results)
print(f"\nFound React on {len(results)}/{len(urls)} sites")
# Version distribution
from collections import Counter
dist = Counter(r["version"] for r in results)
print("\nVersion distribution:")
for ver, count in dist.most_common():
print(f" React {ver}: {count} sites")
For higher throughput, add concurrency with asyncio and aiohttp in Python, or Promise.allSettled in Node.js. Here's a concurrent Node.js version:
async function scanReactVersions(urls, concurrency = 5) {
const results = [];
for (let i = 0; i < urls.length; i += concurrency) {
const batch = urls.slice(i, i + concurrency);
const promises = batch.map(async (url) => {
const res = await fetch(
`https://stackpeek.web.app/api/v1/scan?url=${encodeURIComponent(url)}`
);
const data = await res.json();
const react = data.technologies?.find(
t => t.name.toLowerCase() === 'react'
);
return {
url,
hasReact: !!react,
version: react?.version || null,
confidence: react?.confidence || null
};
});
const settled = await Promise.allSettled(promises);
results.push(
...settled
.filter(r => r.status === 'fulfilled')
.map(r => r.value)
);
}
return results;
}
Use Cases in Detail
Security auditing and compliance
React versions matter for security. Older versions of React are susceptible to certain XSS vectors through unsafe HTML rendering patterns that were tightened in later releases. React 18 introduced stricter hydration that catches mismatches which could lead to content injection. If you manage a portfolio of web applications — as a CISO, security consultant, or compliance officer — scanning all your properties for React versions gives you an instant risk matrix. Sites running React versions older than 18.x should be flagged for upgrade assessment.
M&A technical due diligence
When evaluating an acquisition target, the frontend framework version is a surprisingly useful signal. A company running React 19 with modern patterns is likely investing in their engineering team and keeping their stack current. A company still running React 16 with class components has accumulated years of technical debt that will cost real money to address post-acquisition. Scanning the target's web properties (main site, admin panels, customer portals) gives you this data in minutes rather than waiting for engineering interviews.
Lead generation for React consultancies
If your agency helps companies upgrade their React stack, your ideal customer is running React 16 or 17 and has a complex production application. Scan industry directories, build a list of sites using outdated React versions, and you have a qualified outreach list. The pitch writes itself: "We noticed your main application is running React 16.14. The migration to React 19 unlocks Server Components, concurrent rendering, and significant performance improvements. Here's a scoping estimate."
Technology market research
Analysts tracking React adoption can use batch scanning to answer questions like: What percentage of the top 10,000 SaaS products have upgraded to React 19? Which industries are slowest to upgrade? What's the distribution of React versions across enterprise vs. startup sites? This data powers market reports, investor theses, and technology trend analysis.
Competitive intelligence
Tracking your competitors' React version over time reveals their engineering priorities. If a competitor upgrades from React 17 to React 19, they are likely rebuilding significant portions of their frontend. That upgrade takes engineering resources away from feature development. Conversely, if they stay on an old version while you upgrade, you gain a technical advantage in performance and developer experience that compounds over time.
Comparison: StackPeek vs Manual DevTools vs Wappalyzer
| Criteria | StackPeek API | Manual DevTools | Wappalyzer API |
|---|---|---|---|
| React version detection | Yes, with version number | Yes, with extension | Yes, with version number |
| Automated / scriptable | Yes (REST API) | No (manual) | Yes (REST API) |
| Batch scanning | Yes, thousands of URLs | No (one at a time) | Yes |
| Requires browser | No | Yes | No |
| Confidence scoring | Yes (0-1 scale) | No | No |
| Free tier | 100 scans/day | Unlimited (manual) | Limited |
| Paid plans start at | $9/mo (5,000 scans) | Free | $250/mo |
| Detects framework ecosystem | Yes (Next.js, Gatsby, Remix) | Partial | Yes |
| Setup time | 0 minutes (no API key) | 2 minutes (install extension) | 5 minutes (get API key) |
For one-off checks, the React DevTools extension is fine. For anything beyond a handful of sites — security audits, market research, lead generation — you need an API. StackPeek is 28x cheaper than Wappalyzer and requires zero setup for the free tier.
Detect React versions for free
100 scans per day. No API key. No credit card. One GET request and you know the version.
Try StackPeek free →Understanding React Version Signals
To appreciate what StackPeek does under the hood, it helps to understand the version-specific fingerprints React leaves behind:
- React 15 and earlier:
data-reactidattributes on every DOM element. Distinctive comment nodes in the rendered HTML. These are unmistakable and easy to detect statically. - React 16: Replaced
data-reactidwith a singledata-reactrooton the root element. Introduced error boundaries and portals. The bundle often includesreact.production.min.jswith version strings like"16.14.0". - React 17: No new DOM attributes, but changed the event delegation from
documentto the root container. The JSX transform changed, so build artifacts look different. Version strings in bundles shifted to"17.0.x". - React 18: Introduced
createRootinstead ofReactDOM.render. The__REACT_DEVTOOLS_GLOBAL_HOOK__reports version 18.x. Server-rendered HTML includes streaming markers that are detectable in the page source. - React 19: Server Components generate distinctive serialization patterns in the HTML. The
use()hook and Actions API leave traces in bundled code. RSC payloads are detectable in network requests and inline scripts.
StackPeek checks all of these signals, weighs them by reliability, and returns a single confidence-scored result. You don't need to know which signal was used — you just get the version.
Getting Started in 60 Seconds
- Open your terminal and run:
curl "https://stackpeek.web.app/api/v1/scan?url=github.com" - Check the response for
"name": "React"and the"version"field in the technologies array. - Scale up with the batch scanning scripts above when you need to check hundreds or thousands of URLs.
- Upgrade to Starter ($9/mo) when you exceed 100 scans/day and need higher throughput.
No sign-up required for the free tier. No API key. Just send a request and get structured results. You can also generate social preview images for your tools with OGPeek, or audit SEO alongside tech detection with SEOPeek.
Frequently Asked Questions
How can I check what React version a website is using?
The fastest programmatic method is the StackPeek API. Send a GET request to https://stackpeek.web.app/api/v1/scan?url=example.com and check the response for React in the detected technologies, including the version number. Manual methods include using the React DevTools browser extension or accessing __REACT_DEVTOOLS_GLOBAL_HOOK__ in the browser console, but these do not scale for checking multiple sites.
Can I detect React version without installing React DevTools?
Yes. You can check the page source for references to react.production.min.js or react-dom.production.min.js which often contain version numbers in file paths or inline comments. You can also look for data-reactroot (React 16+) or data-reactid (React 15 and earlier) attributes in the HTML. For fully automated detection without any browser extensions or manual work, the StackPeek API detects React and its version from a single HTTP request.
Why would I need to detect React versions at scale?
Common use cases include: security auditing to find sites running outdated React versions with known vulnerabilities, M&A due diligence to assess technical debt in acquisition targets, competitive analysis to understand competitors' technology choices, lead generation for React consulting and migration services, and technology market research tracking React adoption across industries.
Does StackPeek detect the specific React version number?
Yes. StackPeek detects both the presence of React and the specific version number (e.g., "18.2.0", "19.0.0") when the version is exposed in the page source, bundled assets, or JavaScript runtime. The response includes a version field alongside the technology name and confidence score. For sites that aggressively minify and strip all version identifiers, StackPeek may detect React without a specific version number.
How accurate is React version detection?
React is one of the easier frameworks to detect because it leaves multiple fingerprints: the __REACT_DEVTOOLS_GLOBAL_HOOK__ object, data-reactroot attributes, and version strings in bundled JavaScript. StackPeek combines all of these signals for high-confidence detection. Accuracy for React presence is above 95%. Version-level accuracy depends on whether the site exposes version strings in its bundles, which the majority of production React sites do.
Ready to build your React version detection pipeline? Start with the free tier and scale from there.
Try the live scanner → | Read the API docs → | View pricing →