This error occurs when attempting to use the useTransition hook in a React application that either doesn't have React 18+ installed, isn't using concurrent rendering, or is using an incompatible build bundle that lacks concurrent features. The issue typically arises from version mismatches, incorrect rendering APIs, or bundler configuration problems.
This error indicates that React cannot access the useTransition hook because the concurrent rendering features it depends on are not available in your current React bundle. The useTransition hook was introduced in React 18 as part of React's concurrent rendering system, which allows developers to mark state updates as non-urgent ("transitions"), enabling React to prioritize user interactions and keep the interface responsive. The underlying issue is that concurrent rendering is opt-in in React 18 — it's only enabled when you explicitly use concurrent features through specific APIs like useTransition, startTransition, Suspense, or newer rendering methods like createRoot. If your bundle is using an older version of React, missing concurrent support, or using legacy rendering APIs, React cannot provide the useTransition functionality. Understanding this error is essential for modern React development because useTransition is crucial for building responsive UIs, especially when handling complex state updates or data fetching that might otherwise block the main thread.
Check that your package.json has React 18.0.0 or higher installed:
npm ls reactLook at the version shown. If it's below 18.0.0, upgrade React and React DOM:
npm install react@latest react-dom@latestOr install a specific React 18+ version:
npm install [email protected] [email protected]After upgrading, clear your node_modules and reinstall:
rm -rf node_modules package-lock.json
npm installConcurrent rendering is only enabled when using the modern rendering API. Update your application's entry point to use createRoot instead of the legacy render method.
Before - Legacy API (no concurrent rendering):
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);After - Modern API (concurrent rendering enabled):
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);Note the change from react-dom to react-dom/client in the import. This is essential for enabling concurrent features.
Ensure your bundler (webpack, Vite, Parcel, etc.) is resolving React to the correct build. Check that it's not forcing an old or compatibility build.
For Webpack:
// webpack.config.js
module.exports = {
resolve: {
alias: {
react: require.resolve('react')
}
}
};For Vite:
No special configuration needed. Vite automatically resolves to the modern React build from node_modules.
Verify the React entry point:
# Check which React file is being loaded
node -e "console.log(require.resolve('react'))"It should point to a file in node_modules/react that includes concurrent rendering support.
Create React App has specific version requirements to fully support React 18 and concurrent features.
npm install [email protected] --saveOr update to the latest version:
npm install react-scripts@latest --saveThen restart your development server:
npm startIf you still have issues after updating react-scripts, eject from Create React App (note: this is permanent):
npm run ejectThen ensure your webpack config uses createRoot instead of render.
Sometimes the issue is stale cached bundles or build artifacts.
# Clean build
rm -rf node_modules package-lock.json
npm install
npm run buildFor development:
# Stop dev server (Ctrl+C)
# Clear any cached files
rm -rf .next build dist
# Restart
npm run devClear browser cache:
- Chrome: DevTools > Settings > Cache > Clear site data
- Or use hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
Hard refresh ensures you're loading the latest bundled React code.
In Next.js 12 and later, React 18 concurrent features should be automatically available in App Router projects. Check your setup:
Next.js 13+ with App Router:
Concurrent features are enabled by default. Just use useTransition normally:
// app/components/SearchComponent.tsx
'use client'; // Must be a Client Component
import { useTransition } from 'react';
export function Search() {
const [isPending, startTransition] = useTransition();
return (
<button onClick={() => startTransition(() => {
// Your state update here
})}>
{isPending ? 'Loading...' : 'Click me'}
</button>
);
}Next.js 12 with Pages Router:
Ensure you're using the latest next version:
npm install next@latestServer Components (which don't support hooks) shouldn't use useTransition — mark components with 'use client' at the top.
If you're loading React from a CDN (not recommended for modern apps), ensure it's React 18+:
Bad - Old CDN build:
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>Good - React 18 CDN:
<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>However, CDN-loaded React is not recommended for modern React applications. Use npm/yarn to manage your React dependency instead:
npm install react react-domAnd remove any CDN script tags from your HTML file.
Concurrent Rendering Characteristics: In React 18, concurrent rendering is automatically enabled when you use specific APIs like useTransition, startTransition, useDeferredValue, and Suspense. You don't need to explicitly "turn on" concurrent mode—it activates implicitly when these features are used. This differs from earlier React 18 alpha versions which had an explicit Concurrent Mode API.
Build Bundle Differences: Some bundlers or build tools might provide different React bundles for different environments. The bundle used in production might differ from development. If useTransition works in dev but not production, check your build configuration and ensure both environments resolve to React 18's main entry point.
Edge Runtime Constraints: If you're using Next.js Edge Runtime or similar edge computing environments, concurrent features might be limited. Edge functions have restricted APIs and may not support all React 18 features. Check your framework's documentation for specific constraints.
Performance Impact of useTransition: Using useTransition doesn't guarantee better performance—it's a tool for managing UI interactivity during state updates. Excessive use of transitions for all updates can actually reduce responsiveness. Use transitions only for updates you expect to take significant time, like complex filtering or searching.
Migration from startTransition to useTransition: If you're using the standalone startTransition function and want to track whether a transition is pending (using isPending), you must switch to useTransition hook. startTransition doesn't provide pending state feedback.
Testing with useTransition: When testing components that use useTransition, ensure your test framework doesn't use ReactDOM.render() under the hood. Modern testing libraries like React Testing Library handle this correctly. If you see this error in tests, verify your test setup uses modern React rendering APIs.
Monorepo Issues: In monorepo setups, different packages might have different React versions installed. This can cause useTransition to be unavailable in some packages but not others. Use npm/yarn workspaces with proper hoisting to ensure all packages share the same React version, or use resolutions in your root package.json.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React