Try out React 19 in ESM without build tools

I’ve created quite a few React demos on this blog with React@18 UMD builds, because it is quite helpful to quickly try out React without build tools, following is the code from one of the demos.

<html>
<body>
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>

UMD version of React

<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>

Babel transforms JSX for us

<style>
{...}
.App {
font-family: sans-serif;
text-align: center;
}
.text {
height: 20px;
}
.cells {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 50px;
}
.cell {
width: 10px;
height: 10px;
}
.cell.green {
background-color: green;
}
.cell.gray {
background-color: #ccc;
}
</style>
<div id="container"></div>
<script type="text/babel">
const COLORS = ["green", "gray"];
const useState = React.useState;
function Cell() {
{...}
const start = Date.now();
while (Date.now() - start < 1) {}
return <span className={`cell ${COLORS[Math.round(Math.random())]}`} />;
}
function _Cells() {
{...}
return (
<div className="cells">
{new Array(1000).fill(0).map((_, index) => (
<Cell key={index} />
))}
</div>
);
}
const Cells = React.memo(_Cells);
function App() {
{...}
const [text, setText] = useState("");
const deferrredText = React.useDeferredValue(text);
return (
<div className="app">
demo forked from{" "}
<p>
<a href="https://codesandbox.io/s/react-concurrent-mode-demo-forked-65tu6y?file=/src/index.js">
here
</a>
</p>
<label>
Enter some text to see that it is responding:
<input
type="text"
value={text}
onChange={(e) => {
setText(e.target.value);
}}
/>
</label>
<p>
below is huge amount of cells trying to slow down your rendering
</p>
<p>
but they fail to, since they are rendered in transition, low
priority lane
</p>
<Cells text={deferrredText} />
<p className="text">{text}</p>
</div>
);
}
const rootElement = document.getElementById("container");
ReactDOM.createRoot(rootElement).render(<App />);
</script>
</body>
</html>
<html>
<body>
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>

UMD version of React

<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>

Babel transforms JSX for us

<style>
{...}
.App {
font-family: sans-serif;
text-align: center;
}
.text {
height: 20px;
}
.cells {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 50px;
}
.cell {
width: 10px;
height: 10px;
}
.cell.green {
background-color: green;
}
.cell.gray {
background-color: #ccc;
}
</style>
<div id="container"></div>
<script type="text/babel">
const COLORS = ["green", "gray"];
const useState = React.useState;
function Cell() {
{...}
const start = Date.now();
while (Date.now() - start < 1) {}
return <span className={`cell ${COLORS[Math.round(Math.random())]}`} />;
}
function _Cells() {
{...}
return (
<div className="cells">
{new Array(1000).fill(0).map((_, index) => (
<Cell key={index} />
))}
</div>
);
}
const Cells = React.memo(_Cells);
function App() {
{...}
const [text, setText] = useState("");
const deferrredText = React.useDeferredValue(text);
return (
<div className="app">
demo forked from{" "}
<p>
<a href="https://codesandbox.io/s/react-concurrent-mode-demo-forked-65tu6y?file=/src/index.js">
here
</a>
</p>
<label>
Enter some text to see that it is responding:
<input
type="text"
value={text}
onChange={(e) => {
setText(e.target.value);
}}
/>
</label>
<p>
below is huge amount of cells trying to slow down your rendering
</p>
<p>
but they fail to, since they are rendered in transition, low
priority lane
</p>
<Cells text={deferrredText} />
<p className="text">{text}</p>
</div>
);
}
const rootElement = document.getElementById("container");
ReactDOM.createRoot(rootElement).render(<App />);
</script>
</body>
</html>

But UMD builds are no longer shipped with React 19, instead we can try out the esm builds provided by esm.sh.

Below is a working example of the same demo in ESM builds of React@19, you can also try it out.

<html>
<body>
<style>
{...}
.App {
font-family: sans-serif;
text-align: center;
}
.text {
height: 20px;
}
.cells {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 50px;
}
.cell {
width: 10px;
height: 10px;
}
.cell.green {
background-color: green;
}
.cell.gray {
background-color: #ccc;
}
</style>
<div id="container"></div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

Babel transforms JSX for us

<script type="text/babel" data-type="module">

Don't forget to set the module type

import React from "https://esm.sh/[email protected]";
import ReactDOMClient from "https://esm.sh/[email protected]/client";

Import from esm builds of React

const COLORS = ["green", "gray"];
const useState = React.useState;
function Cell() {
{...}
const start = Date.now();
while (Date.now() - start < 1) {}
return <span className={`cell ${COLORS[Math.round(Math.random())]}`} />;
}
function _Cells() {
{...}
return (
<div className="cells">
{new Array(1000).fill(0).map((_, index) => (
<Cell key={index} />
))}
</div>
);
}
const Cells = React.memo(_Cells);
function App() {
{...}
const [text, setText] = useState("");
const deferrredText = React.useDeferredValue(text);
return (
<div className="app">
demo forked from{" "}
<p>
<a href="https://codesandbox.io/s/react-concurrent-mode-demo-forked-65tu6y?file=/src/index.js">
here
</a>
</p>
<label>
Enter some text to see that it is responding:
<input
type="text"
value={text}
onChange={(e) => {
setText(e.target.value);
}}
/>
</label>
<p>
below is huge amount of cells trying to slow down your rendering
</p>
<p>
but they fail to, since they are rendered in transition, low
priority lane
</p>
<Cells text={deferrredText} />
<p className="text">{text}</p>
</div>
);
}
const rootElement = document.getElementById("container");
ReactDOMClient.createRoot(rootElement).render(<App />);
</script>
</body>
</html>
<html>
<body>
<style>
{...}
.App {
font-family: sans-serif;
text-align: center;
}
.text {
height: 20px;
}
.cells {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 50px;
}
.cell {
width: 10px;
height: 10px;
}
.cell.green {
background-color: green;
}
.cell.gray {
background-color: #ccc;
}
</style>
<div id="container"></div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

Babel transforms JSX for us

<script type="text/babel" data-type="module">

Don't forget to set the module type

import React from "https://esm.sh/[email protected]";
import ReactDOMClient from "https://esm.sh/[email protected]/client";

Import from esm builds of React

const COLORS = ["green", "gray"];
const useState = React.useState;
function Cell() {
{...}
const start = Date.now();
while (Date.now() - start < 1) {}
return <span className={`cell ${COLORS[Math.round(Math.random())]}`} />;
}
function _Cells() {
{...}
return (
<div className="cells">
{new Array(1000).fill(0).map((_, index) => (
<Cell key={index} />
))}
</div>
);
}
const Cells = React.memo(_Cells);
function App() {
{...}
const [text, setText] = useState("");
const deferrredText = React.useDeferredValue(text);
return (
<div className="app">
demo forked from{" "}
<p>
<a href="https://codesandbox.io/s/react-concurrent-mode-demo-forked-65tu6y?file=/src/index.js">
here
</a>
</p>
<label>
Enter some text to see that it is responding:
<input
type="text"
value={text}
onChange={(e) => {
setText(e.target.value);
}}
/>
</label>
<p>
below is huge amount of cells trying to slow down your rendering
</p>
<p>
but they fail to, since they are rendered in transition, low
priority lane
</p>
<Cells text={deferrredText} />
<p className="text">{text}</p>
</div>
);
}
const rootElement = document.getElementById("container");
ReactDOMClient.createRoot(rootElement).render(<App />);
</script>
</body>
</html>

Want to know more about how React works internally?
Check out my series - React Internals Deep Dive!

😳 Share my post ?    
or sponsor me

❮ Prev: React Internals Explorer - easily see how React works