React displays user interfaces by mounting a component tree into a single HTML container element. In React 18 and React 19, you import createRoot from react-dom/client to connect your JavaScript tree to the browser DOM. The older ReactDOM.render function was removed in React 19.
Every single-page React app starts with an HTML file that defines one empty mount node, usually <div id="root"></div>. Your entry script grabs that node with document.getElementById and calls createRoot(container).render(...).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Storefront App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
flowchart LR
HTML["index.html (#root)"] --> JS["main.jsx createRoot()"]
JS --> Tree["root.render(<App />)"]
Tree --> DOM["Live Interactive UI"]
createRoot enables React's concurrent renderer, which prioritizes urgent user actions like typing ahead of slow background updates. It also unlocks automatic batching across promises, timeouts, and native event listeners so multiple state updates trigger a single re-render.
createRoot(document.getElementById('root')) throws an error if the <div id="root"> element does not exist or loads after your script without type="module".createRoot Inside Re-renders: You should create a root only once per container. Repeatedly calling createRoot resets component state and logs React warnings.ReactDOM.render: Tutorials from React 17 still import ReactDOM.render. Replace it with createRoot from react-dom/client in React 19.Yes. You can mount React inside any <div> on a server-rendered page without turning the whole website into a single-page app.
root.render overwrite existing HTML inside #root?Yes. Anything placed inside <div id="root"></div> is replaced once React mounts, though server-rendered apps can use hydrateRoot to attach to existing markup.
<App /> wrapped in <StrictMode>?<StrictMode> runs extra development checks to surface unsafe side effects and deprecated APIs without changing production behavior.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
You've completed this section! Take a quick 5-question quiz to check your understanding.