If you’ve worked with React for a while, you probably remember this familiar line of code:
ReactDOM.render(<App />, document.getElementById("root"));
But starting from React 18, you’ll see a new approach:
import { createRoot } from "react-dom/client";const root = createRoot(document.getElementById("root"));root.render(<App />);
So the obvious question is:
👉 Why did React introduce createRoot and move away from ReactDOM.render?
Let’s break it down simply.
What is ReactDOM.render()?
ReactDOM.render() was the traditional way to render a React application into the DOM.
Example (Before React 18)
import ReactDOM from "react-dom";import App from "./App";ReactDOM.render(<App />, document.getElementById("root"));
How it worked
- React rendered the entire UI synchronously
- Updates happened immediately
- Simple and easy, but limited for performance optimizations
What is createRoot()?
createRoot() is the new rendering API introduced in React 18.
Example (React 18 and above)
import { createRoot } from "react-dom/client";import App from "./App";const root = createRoot(document.getElementById("root"));root.render(<App />);
How it works
- Enables Concurrent Rendering
- React can pause, resume, or abandon renders
- Makes apps smoother and more responsive
Why Did React Introduce createRoot()?
The change was made to support modern React features.
Key reasons:
1. Concurrent Rendering
React can:
- Work on multiple UI updates at the same time
- Prioritize important updates (like user input)
- Delay less important renders
This was not possible with ReactDOM.render().
2. Better Performance
With createRoot:
- Large UI updates don’t block the main thread
- The app feels more responsive
- Smooth animations and transitions
3. Foundation for New Features
Many React 18 features only work with createRoot:
startTransition- Automatic batching
- Streaming server-side rendering
- Suspense improvements
What Happens If You Still Use ReactDOM.render()?
- It still works, but:
- Runs React in legacy mode
- You won’t get React 18 performance benefits
- You may see warnings in future versions
👉 React recommends migrating to createRoot.
Key Differences at a Glance
| Feature | ReactDOM.render | createRoot |
|---|---|---|
| Introduced in | React 16 | React 18 |
| Rendering type | Synchronous | Concurrent |
| Performance | Good | Better |
| Supports new features | ❌ No | ✅ Yes |
| Future-proof | ❌ | ✅ |
Should You Migrate?
✅ Yes, if:
- You’re using React 18
- You want better performance
- You plan to use new React features
Migration is simple and usually requires changing just a few lines.
Final Thoughts
The shift from ReactDOM.render() to createRoot() is not just a syntax change —
it’s a major architectural upgrade in how React handles rendering.
Even though the old way still works, createRoot is the future of React.
Small change in code, big improvement in performance.
Discover more from Learners Store
Subscribe to get the latest posts sent to your email.