How to fix useId is not available in this React build in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025· 139 views

React raises this error whenever the bundle that ends up in the browser is still running a build that predates React 18 or resolves to a different runtime than the one supplying <code>useId</code>. The hook was introduced in React 18 for stable ID generation, so any version mismatch, duplicate React resolution, or legacy CDN script that delivers React 17 causes the runtime to throw before your components render. This guide walks through the typical traps (duplicate versions, bundler aliases, cached scripts) and the steps to lock everything on React 18+ so the hook is actually available.

Quick fix

Fixes useId is not available in this React build

npm install react@18 react-dom@18
  1. Confirm React 18+ is actually installed
  2. Deduplicate React so only one copy ships
  3. Ensure the bundler resolves the modern React entry
  4. Purge caches and rebuild the entire bundle
react — error
npm install react@18 react-dom@18
useId is not available in this React build
shell
npm install react@18 react-dom@18

What this error means

React throws this error when the copy of React that the browser actually executes does not export the <code>useId</code> hook. <code>useId</code> was introduced in React 18 to generate deterministic IDs that hydrate safely across server and client renders. Older React builds (React 17 and earlier) simply do not have this hook. The message is therefore a symptom of a version mismatch, duplicate React packages, or a bundler/resolution configuration that still loads a legacy entry point. Once the runtime bundle resolves to React 18 or newer, the hook exists and the error disappears. Ensuring both <code>react</code> and <code>react-dom</code> are aligned and that only one copy of the package ships is the key to fixing this.

Typical symptoms

  • Runtime exception saying "useId is not available in this React build" as soon as a component renders or hydration begins.
  • Stack traces point into React’s hook layer (React dev/production builds) even though the component only imports useId.
  • Only appears after bundling for production while `npm run dev` works, because production builds still resolve an older React bundle.
  • Third-party React 18 libraries or UI kits blow up in hosts that still ship React 17 or earlier.
  • `npm ls react` reports multiple versions or still lists 17.x versions despite installing React 18.
  • Server-side rendering succeeds but the client bundle crashes, indicating the server and client bundles use different React versions.
  • The same page worked yesterday until a service worker, CDN cache, or legacy script reinjected React 17, so the build is stale.

Common causes

  1. The project depends on React 17 or earlier; useId exists only in React 18.0.0 and later.
  2. react-dom is pinned to a version below 18, so the DOM renderer cannot provide the hook even if `react` is newer.
  3. Multiple React copies exist in node_modules (monorepo/workspace) and the oldest one is bundled, lacking useId.
  4. Webpack/Vite/other build tooling resolves an alias to a legacy UMD entry (e.g., react.production.min.js from React 17).
  5. A dependency built for React 18 is imported into an app that still runs React 17, so the host React throws as soon as the dependency uses useId.
  6. Compatibility shims such as preact/compat, older CDN scripts, or global window.React references point to a build without useId.
  7. Bundler caches, service workers, or CDN edge caches still serve the old React bundle after you upgraded dependencies.
  8. Lockfiles or shrinkwrap entries still pin React below 18, so fresh installs keep pulling the wrong version.
  9. Server and client bundles were built with different React versions (e.g., the server bundles React 18 but the client bundle falls back to React 17).

How to fix "useId is not available in this React build"

1Confirm React 18+ is actually installed

Run npm ls react react-dom (or pnpm ls/yarn why) to see which versions are currently resolved. If either dependency shows a version below 18.0.0, upgrade both packages together:

bash
npm install react@18 react-dom@18

or lock to a specific patch:

bash
npm install react@18.2.0 react-dom@18.2.0

After installing, clear module caches (rm -rf node_modules package-lock.json pnpm-lock.yaml) and reinstall to ensure the new versions are the only ones on disk.

2Deduplicate React so only one copy ships

Monorepo setups or transitive dependencies often install multiple React versions. Use dedupe commands (e.g., npm dedupe, pnpm dedupe, yarn install --check-files) and re-run npm ls react until only the React 18 copy remains. If you are using Yarn or pnpm workspaces, add a resolutions (Yarn) or packageExtensions (pnpm) entry so every package resolves to the same React version.

json
// package.json (Yarn)
"resolutions": {
  "react": "18.2.0",
  "react-dom": "18.2.0"
}

Then rerun your installer and rebuild.

3Ensure the bundler resolves the modern React entry

Ask Node which file is being loaded in the build:

bash
node -p "require.resolve('react')"
node -p "require.resolve('react-dom')"

They should point into node_modules/react and not into any vendor/CDN shim. If you see absolute paths pointing to a legacy folder, adjust your bundler’s resolve.alias so react and react-dom both resolve to your root node_modules. Vite typically resolves correctly, but Webpack projects may have leftover aliases from older migrations that still point to older builds.

4Purge caches and rebuild the entire bundle

After touching dependencies or resolution overrides, remove build artifacts so the next compile can pull fresh modules:

bash
rm -rf node_modules package-lock.json pnpm-lock.yaml
npm install
rm -rf dist .next build
npm run build

Also clear any service worker or CDN caches that might still serve the old bundle, and hard-refresh the browser (Ctrl+Shift+R / Cmd+Shift+R) when testing.

5Check for legacy React scripts in HTML or CDNs

Search your HTML template for <script ... react tags. Remove any statements that load React 17 from a CDN, because they override your bundled React 18 with an older runtime. If you absolutely need a CDN build, make sure it is React 18:

html
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

Using npm-managed packages is still preferred, but if you reference CDN scripts, always point them to a matching React 18 build.

6Upgrade framework/glue code (CRA, Next.js, etc.)

Frameworks that ship their own React version also need to be on a React 18 release. For Create React App, install react-scripts 5.0.0 or later:

bash
npm install react-scripts@5

In Next.js, run npm install next@latest (Next 12.1+ automatically ships React 18) and use the App Router or Client Components for parts that call hooks like useId. Make sure any custom entry points use ReactDOM.createRoot instead of the legacy render so the client bundle uses the modern renderer.

Advanced notes

<strong>Why useId exists:</strong> React 18 introduced useId to emit deterministic IDs that survive SSR and hydration, avoiding duplicated IDs or mismatched aria attributes. The hook internally generates a prefix and counter that depend on the renderer, so the client and server must run the same React build. If useId throws, it usually means the client is still executing a build that predates React 18 or is not the build bundled by your module system (e.g., global scripts, CDN caches, or duplicate installs).<br/><br/><strong>Hydration alignment:</strong> When using server rendering we adapt a special _document or template. The React renderer uses underscores in new SSR builds, so mismatched versions can also show useId errors even when the source code has the hook. For consistent hydration, keep both server and client bundles on the same React 18+ release.

Frequently asked questions

What does "useId is not available in this React build" mean?
React throws this error when the copy of React that the browser actually executes does not export the <code>useId</code> hook. <code>useId</code> was introduced in React 18 to generate deterministic IDs that hydrate safely across server and client renders. Older React builds (React 17 and earlier) simply do not have this hook.
How do I fix "useId is not available in this React build"?
React raises this error whenever the bundle that ends up in the browser is still running a build that predates React 18 or resolves to a different runtime than the one supplying <code>useId</code>. The hook was introduced in React 18 for stable ID generation, so any version mismatch, duplicate React resolution, or legacy CDN script that delivers React 17 causes the runtime to throw before your components render. This guide walks through the typical traps (duplicate versions, bundler aliases, cached scripts) and the steps to lock everything on React 18+ so the hook is actually available.
What causes "useId is not available in this React build"?
The project depends on React 17 or earlier; useId exists only in React 18.0.0 and later. react-dom is pinned to a version below 18, so the DOM renderer cannot provide the hook even if react is newer. Multiple React copies exist in node_modules (monorepo/workspace) and the oldest one is bundled, lacking useId.
Is the "useId is not available in this React build" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading