One HTML file, zero build — React 19 + Babel
<JSX> into
React.createElement(...). Below, edit the JSX in the box, hit
compile & render, and watch it flow:
JSX → Babel →
element tree → live DOM.
| CDN script | role | what it gives you |
|---|---|---|
react@19.2.7esm.sh ?dev |
the runtime | React.createElement, hooks (useState), React.version |
react-dom@19.2.7/clientesm.sh ?dev |
the DOM renderer | createRoot — the React 19 mount API (no more ReactDOM.render) |
@babel/standalone@8.0.3jsDelivr |
the compiler | Babel.transform(src,{presets:[['react',{runtime:'classic'}]]}) → React.createElementBabel 8 defaults to automatic (jsx-runtime imports) — force classic here |
React 19 dropped UMD. The old
unpkg.com/react@19/umd/react.development.js no longer exists — React
ships only ESM now, so we import() it from esm.sh and assign it to
window ourselves. (Full story + sources in the guide.)
1 · the JSX you write (edit me)
2 · Babel compiles JSX into an element tree
Babel transforms <App/> into
React.createElement(App). This plain-JS call returns a plain
object — a React element, the description of a node. That object tree
is what React actually works with.
// (hit “compile & render” to see Babel’s output here)
3 · createRoot renders the tree into the DOM
createRoot(document.getElementById('root')).render(<App/>)
is the React 19 mount call. React walks the element tree and produces real
DOM nodes inside #root. Click the button in the card — that is
live React state (the n re-render proves it).
mount node #root children: 0
· rendered text: —