React Install: The 7.5 MB You Asked For, and the 734 MB You Didn't
npm ci on this storefront installs 633 packages and 742 MB. React is 7.5 MB of it — what the other 99% is, and which of the three install paths to pick.
Every "how to install React" guide stops at the command that finishes successfully. None of them tell you what landed on your disk. So here is that number from a real production app: npm ci on this storefront installs 633 packages and 742 MB, of which React itself is 7.5 MB. One percent. The install decision that matters is not how to install React — it is what you install around it.
The short answer
Install Node.js, then scaffold with a framework rather than installing React bare: npm create vite@latest for a client-side app, or npx create-next-app@latest for one that also renders on the server. npm install react react-dom alone works only if you already have a bundler, because browsers cannot execute JSX. The commands are identical on Windows, macOS and Linux.
The three ways to install React
| Path | Command | What you get | Use when |
|---|---|---|---|
| Framework scaffold | npx create-next-app@latest | React + routing + SSR/SSG + bundler, configured | You are building a site or app with more than one page |
| Bundler scaffold | npm create vite@latest | React + a dev server and build, no routing | You want a single-page app and will pick routing yourself |
| Bare package | npm install react react-dom | The two libraries, nothing else | You already have a bundler and are adding React to it |
React's own documentation points at the first two and describes the third as the "existing project" path — because React is a rendering library, not a toolchain. On its own it cannot transform JSX, serve a dev server, or produce a production bundle. That is the single most useful thing to understand before typing any of these commands: the thing you are installing is never just React.
Prerequisites, and the Windows question
All three paths need Node.js, which ships npm with it. Download the LTS build from nodejs.org and verify:
node --version
npm --version
On Windows the commands above are byte-for-byte identical in PowerShell, Command Prompt, or WSL — React has no platform-specific installer, no separate download, and nothing to add to PATH beyond what the Node.js installer does. The only real Windows-specific advice is to keep the project off a OneDrive-synced folder, because node_modules is hundreds of thousands of small files and background sync makes installs and dev-server restarts noticeably slower.
What a real install actually contains
This is a Next.js 16 + React 19 storefront: 618 prerendered pages, 92 component files, a product catalog, MDX blog and a Supabase-backed commerce layer. Its package.json declares 13 runtime dependencies and 13 dev dependencies:
"dependencies": {
"@mdx-js/loader": "^3.1.1",
"@mdx-js/react": "^3.1.1",
"@next/mdx": "^16.3.0",
"@supabase/ssr": "^0.12.0",
"@supabase/supabase-js": "^2.110.0",
"@vercel/analytics": "^2.0.1",
"lucide-react": "^1.21.0",
"next": "16.2.9",
"react": "19.2.4",
"react-dom": "19.2.4",
"rehype-slug": "^6.0.0",
"remark-gfm": "^4.0.1",
"server-only": "^0.0.1"
}
Twenty-six declared packages resolve to 633 entries in package-lock.json and 440 top-level directories in node_modules. A cold npm ci on this checkout finished in 18 seconds with a warm npm cache; the resulting tree is 742 MB.
Where that 742 MB goes is the part worth seeing:
| Package | On disk | Share |
|---|---|---|
@next (compiler + platform binaries) | 249 MB | 34% |
next | 173 MB | 23% |
lucide-react | 40 MB | 5% |
@rolldown | 37 MB | 5% |
@img (image processing binaries) | 33 MB | 4% |
typescript | 23 MB | 3% |
react + react-dom + scheduler | 7.5 MB | 1% |
React and React DOM together are one percent of the install. The framework and its native binaries are 57%. A single icon library is more than five times the size of React itself.
Two things follow from that table, and both change how you should think about "installing React":
The size is platform binaries, not JavaScript. @next, @img and @rolldown are largely compiled Rust and native image codecs, downloaded per platform. They are build-time tools that never reach a browser. Disk size and shipped bundle size are unrelated numbers: this app's entire client bundle is 1.5 MB across .next/static/chunks — 0.2% of the 742 MB that produced it.
Your dependency choices dominate, not React's. React's own footprint is fixed and small. Everything else on that list is a decision you made. lucide-react at 40 MB is the clearest case: it installs every icon as a separate module so a bundler can tree-shake to the handful you import. Large on disk, near-free in the bundle — but only because the tooling around React does the shaking.
Installing React into a project you already have
If you have a bundler, the bare install is genuinely two packages:
npm install react react-dom
You then need a JSX transform. Every modern bundler has one, but it is a configuration step, not a default — this is the step that turns "React is installed" into "React runs". With Vite it is @vitejs/plugin-react; with a plain esbuild or SWC setup it is a loader option. Skip it and the first .jsx file fails to parse, which is the most common way a bare React install appears broken when it is actually fine.
You also need types if the project is TypeScript:
npm install --save-dev @types/react @types/react-dom
Note that React's own packages are pinned exactly in the package.json above — "react": "19.2.4", no caret — while everything else carries a range. That is deliberate and worth copying: React and React DOM must be the same version, and a floating range on two packages that have to agree is a way to get a mismatched pair from a lockfile refresh. The framework pins them the same way.
Verifying the install did what you think
Four checks, in the order that isolates a failure fastest:
node --version # Node is on PATH
npm ls react react-dom # both resolved, one version each
npm run dev # the dev server boots
npm run build # the production build completes
npm ls react is the one people skip and the one that catches the most. If it prints two different React versions, or a deduped line under a package you did not install, you have a duplicate React in the tree — the cause of "invalid hook call" errors that look like a bug in your component and are not.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Unexpected token '<' on a .jsx file | No JSX transform configured | Add the bundler's React plugin; React does not transform JSX itself |
| "Invalid hook call" after a clean install | Two copies of React in the tree | npm ls react — dedupe, or align the versions and reinstall |
npm install fails on a native dependency | No prebuilt binary for your platform/Node version | Match the Node LTS the project expects; check the package supports your architecture |
| Install is slow or flaky on Windows | Project lives in a OneDrive-synced folder | Move it to a local path; node_modules is too many small files to sync |
node_modules is enormous | Build-time native binaries, not shipped code | Expected — compare bundle output, not disk size |
npm ci fails where npm install worked | Lockfile disagrees with package.json | Run npm install once to reconcile, commit the lockfile |
React version differs from react-dom | Floating ranges on packages that must match | Pin both exactly, as this project does |
Frequently asked questions
Do I need to download React from a website? No. React is distributed through npm and installs with a command; there is no installer or download page. The only thing you download manually is Node.js, which provides npm.
How do I install React on Windows?
The same way as anywhere else: install Node.js from nodejs.org, then run npm create vite@latest or npx create-next-app@latest in PowerShell, Command Prompt or WSL. No platform-specific steps, and no separate React download.
Can I install React without a framework?
Yes — npm install react react-dom — but you still need a bundler with a JSX transform for it to run. "Without a framework" in practice means Vite plus React rather than nothing at all.
Is Create React App still the way to start? No. It is deprecated, and React's documentation now points to framework or bundler scaffolds instead. Existing CRA projects keep working; new ones should use Vite or a framework.
Why is node_modules hundreds of megabytes for a small app?
Because most of it is build tooling and platform-specific native binaries that never ship to a browser. In the measurement above, React is 7.5 MB of 742 MB and the compiler binaries are over half. Judge the build output, not the directory.
Choosing what to install around React
The install is the easy part; the consequential choice is the layer above it. Next.js vs. React + Vite compares the two scaffolds on the axes that actually diverge, and React UI libraries covers the dependency decision that showed up as 40 MB in the table above — this codebase ships zero of them across 92 hand-rolled components. If you want to see where the installed bytes end up at runtime rather than on disk, the bundle analyzer walkthrough measures the other end of the pipeline.
Templates in this post
ASoc Folio, ASoc Forge and ASoc Frame ship with the install decisions above already made — pinned React and React DOM, a lean dependency list, and a build that runs clean from npm install.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates.
