How to detect React on any website
The JavaScript library for building user interfaces — the base most meta-frameworks build on.
By Mapree ·
Official siteWhat is React?
React is a UI library, not a framework — but it's the default UI layer for Next.js, Remix, Gatsby, parts of Astro, React Native, and countless bespoke setups. Its fingerprints overlap with anything that uses it.
React is the most-used library in frontend JavaScript, and that popularity means its traces are both everywhere and deeply variable. A site might use React as the whole frontend (SPA), as the runtime of a meta-framework like Next or Remix, as an island inside an Astro page, as a widget embedded in a WordPress site, as a native wrapper via React Native Web, or as a small interactive component on an otherwise-static page. Detecting React is rarely the question; detecting 'is React the primary UI layer' or 'which React version is this' is what actually matters. Since React 18 the concurrent-rendering features and Server Components have shifted the ecosystem toward hybrid SSR/streaming models, which changes both what you see in the browser (flight payloads, streamed chunks) and what constitutes a confident detection.
Why it matters to identify
Confirming React is the first step before identifying the framework on top (Next, Remix, Gatsby, Astro, bespoke Vite + React, CRA). Version matters because React 18 and 19 enabled concurrent features and server components that older detectors may not surface. Library ecosystem choices correlate strongly with React version — React 19 sites often run Next.js 15, Server Components and the new use() hook, while React 17 sites are still running CRA or legacy SSR stacks.
A brief history of React
React was open-sourced by Facebook in 2013 and has been the dominant JavaScript UI library since around 2016. Major releases: 16 (2017, Fiber reconciliation), 16.8 (2019, hooks), 17 (2020, no new features — stepping stone release), 18 (2022, concurrent rendering), 19 (2024, actions, use() hook, ref-as-prop, form actions, built-in streaming). Each major version shifted what's possible in the ecosystem: hooks redefined component authorship; concurrent rendering redefined the relationship between UI updates and I/O; server components redefined where code runs.
Ecosystem and common pairings
React's immediate ecosystem is enormous. The common companions: a meta-framework (Next, Remix, Gatsby), a state library (Zustand, Redux Toolkit, Jotai), a data-fetching library (TanStack Query, SWR, Apollo Client for GraphQL), a UI kit (shadcn/ui, MUI, Chakra UI, Ant Design), a form library (React Hook Form, Formik, Conform), styling (Tailwind, styled-components, emotion, CSS Modules). The exact combination often fingerprints the team's vintage and taste.
Detection signals we look at
Each signal alone is rarely conclusive; the detector cross-references all of them and weights by confidence. You can reproduce any of these checks yourself in Chrome DevTools.
[data-reactroot]
Legacy SSR React apps set this on the root container. Less common in modern builds.
window.React.version
When React is loaded as an un-bundled global (older sites, CDN-linked), `React.version` is the canonical version string.
node_modules/react-dom/|node_modules/react/
In sourcemaps, paths under `node_modules/react/` and `node_modules/react-dom/` confirm React is bundled, with the exact version in the matching package.json.
react.production.min.js|react-dom.production.min.js
CDN-linked React (common on marketing sites or legacy apps).
data-react-helmet|data-rh
react-helmet and similar meta managers leave telltale `data-*` attributes on head tags.
Versioning
What you typically see in production
On a typical 2025-2026 React site the bundle weighs anywhere from 40 KB (a tightly tree-shaken Preact-compat island) to 400+ KB (a complete dashboard with Recharts, Radix, TanStack Query, react-hook-form and a custom design system). The sourcemap, when exposed, gives the full picture: `node_modules/react/package.json` for the canonical version, `node_modules/react-dom/package.json` for the renderer version (almost always identical), plus `node_modules/scheduler/` for the concurrent-rendering scheduler library that React 18+ ships alongside. You see two distinct deployment shapes in the field. The first is a meta-framework SPA — Next.js or Remix in the lead — where React is bundled deeply and the sourcemap surfaces the entire dependency surface. The second is the island pattern, popularised by Astro, where React appears in localised chunks attached to specific components (`<astro-island>` markers in the DOM, separate hydration scripts, smaller per-island bundles). The island pattern reduces the apparent React footprint dramatically but does not change the per-island detection signals. React 18 and 19 both exist in the wild today. Most production sites are still on 18.2.x or 18.3.x as of mid-2026 (the long tail of `next@14` and the Remix ecosystem); React 19 is concentrated in early-adopter Next.js 15 builds, anything using server actions seriously, and frontier-engineering teams that have moved past the migration tax. Sites that do not look like meta-framework SPAs at all — embedded widgets, WordPress plugin frontends, micro-frontend shells — typically run an older React (16.x, 17.x) because the dependency cost of upgrading is not worth it for a small surface area. A distinctive pattern when you see Server Components in the wild: `self.__next_f.push(...)` calls in inline scripts, RSC flight payload chunks loaded from `/_next/static/chunks/app/`, and a much thinner client bundle than a comparable client-side-rendered React app. The chunk-loading pattern by itself is enough to tell you the site is on App Router with Server Components active, even before you check the version.
Sites commonly running React
- facebook.com
- instagram.com
- airbnb.com
- netflix.com (parts of)
- whatsapp.com
- x.com
Often confused with
React vs Preact
Preact is a smaller React-compatible library. Its bundle is visibly tiny (3-10 KB instead of React's 50+ KB) and paths reference `node_modules/preact/`. If you see `preact/compat` in the sourcemap, the site is using Preact with a React compatibility shim — the developer wrote React-shaped code but ships Preact's runtime, which is a deliberate size-optimisation choice common on marketing sites and small SDKs.
React vs React Native Web
React Native for Web bundles React + React Native primitives. Look for `node_modules/react-native-web/` in the sourcemap. The DOM tree shows `<View>` and `<Text>` components rather than `<div>` and `<span>`, although those compile down to plain HTML elements at runtime.
React vs Inferno / Solid / Qwik
All three are React-influenced or React-compatible JavaScript UI libraries with different rendering models. Inferno's signature is `node_modules/inferno/`; Solid uses a fine-grained reactivity model and shows `node_modules/solid-js/`; Qwik ships its resumable runtime via `node_modules/@builder.io/qwik/`. All three share enough JSX-style syntax with React to look similar in the source, but the bundle paths give them away.
FAQ
How do I tell React 18 from 19?
Only via the sourcemap-embedded `react/package.json` or the `React.version` runtime global when the package exposes it. The bundle output looks similar between majors. New-API presence (`use()` hook calls, form actions, `useFormStatus`, `useActionState`) in the reconstructed source also confirms 19+. App Router sites running on `next@15` are React 19 by default; App Router sites on `next@14` are React 18.x.
Does detecting React tell me the framework?
No — React is the base. You need additional signals (`_next/static/` for Next, `<astro-island>` for Astro, `#___gatsby` for Gatsby, `data-remix-` attributes for Remix) to identify the framework on top. See the [detect-framework-of-any-website](/how-to/detect-framework-of-any-website) guide for the full flow.
What's the easiest way to read the React version?
Open the dev console and type `React.version` — if React is exposed as a global, that returns the canonical version string. Most modern bundled apps do not expose the global; for those, Sourcemap Explorer reads `node_modules/react/package.json` from the sourcemap and shows the exact version in the popup.
Why do some sites bundle two Reacts?
Almost always a peer-dependency hoisting accident. A library you depend on (or a UI kit, or a charting widget) pinned a slightly different React major and the package manager could not dedupe them. The result is two Reacts in the bundle, which is both a performance regression (extra bytes shipped) and a correctness risk (two reconcilers means two virtual DOMs). Sourcemap Explorer surfaces both versions when this happens.
Can I tell if a site is using Server Components?
Yes. The presence of `self.__next_f.push(...)` calls in inline scripts plus chunks loaded from `/_next/static/chunks/app/` (rather than `/pages/`) plus the absence of `__NEXT_DATA__` is the canonical signature. Sourcemap Explorer surfaces the App Router router type directly when reading the Next.js metadata.
Why doesn't Wappalyzer give me a React version?
Because Wappalyzer's regex-based detection runs against URLs and headers, not against the bundle interior. The exact React version lives inside `node_modules/react/package.json` as embedded source content in the sourcemap, which sourcemap-aware tools can read and Wappalyzer-style detectors structurally cannot.
Related
See React — with the exact version — on every site you visit.
Sourcemap Explorer runs these checks passively in the background. When the target library is bundled, you get the precise package.json-level version.