How to Create a React JS App with CDN: Complete Guide to UMD Bundles
Yes, you can create a fully functional React JS application using CDN links by loading the UMD bundles for react and react-dom, which expose the framework as global objects on the window object without requiring build tools like webpack or Vite.
React is primarily distributed as npm packages within the facebook/react repository, but it also provides pre-compiled UMD bundles that allow you to use React JS with CDN directly in the browser. This approach eliminates the need for complex build configurations, making it ideal for quick prototypes, legacy integrations, or educational environments where you want to demonstrate React functionality immediately.
How React CDN Bundles Work
The React repository builds UMD (Universal Module Definition) bundles from the source packages located in packages/react and packages/react-dom. According to the facebook/react source code, the entry points for these bundles are defined in packages/react/src/React.js and packages/react-dom/src/client/ReactDOM.js.
When you include the CDN scripts in your HTML, they execute immediately and attach the public APIs to the global window object as window.React and window.ReactDOM. These globals expose the same methods—such as React.createElement, React.useState, and ReactDOM.createRoot—that you would import in a module-bundled project.
The CDN provides two build variants:
- Production builds (
react.production.min.js) – Minified and optimized, with warnings stripped for maximum performance. - Development builds (
react.development.js) – Include verbose warnings and error messages to help catch common mistakes during development.
Setting Up a React JS App with CDN
Production-Ready Implementation
For a live environment, load the minified production bundles from unpkg. This example creates a simple functional component using React.createElement and renders it with ReactDOM.createRoot:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>React JS with CDN</title>
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
</head>
<body>
<div id="root"></div>
<script>
function HelloWorld(props) {
return React.createElement('h1', null, `Hello, ${props.name}!`);
}
ReactDOM.createRoot(document.getElementById('root')).render(
React.createElement(HelloWorld, {name: 'CDN'})
);
</script>
</body>
</html>
The CDN URLs point to the UMD bundles that the repository publishes. For enhanced security in production, add Subresource Integrity (SRI) hashes to the script tags.
Development Build with Warnings
During development, use the non-minified development builds to access detailed error messages and warnings. Simply change the filenames from production.min.js to development.js:
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
These builds are larger and execute slower but are essential for debugging, as they include the full warning system implemented in packages/react/src/React.js.
Using JSX with React CDN
On-the-Fly Compilation with Babel
Writing React.createElement calls manually is verbose. To use JSX syntax without a build step, include the Babel standalone compiler alongside your React CDN scripts. Babel transforms JSX into React.createElement calls in the browser before execution:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>React JS with CDN and JSX</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>Clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Counter />);
</script>
</body>
</html>
The type="text/babel" attribute instructs the Babel CDN to compile the script contents before execution. This pattern is ideal for quick demos or learning environments, though it adds runtime compilation overhead that makes it unsuitable for production deployments.
Switching Between Development and Production Builds
For applications that need to load different builds based on the environment without manual file editing, dynamically inject the appropriate CDN URLs using JavaScript:
<script>
const isProduction = location.hostname !== 'localhost';
const reactSrc = isProduction
? 'https://unpkg.com/react@18/umd/react.production.min.js'
: 'https://unpkg.com/react@18/umd/react.development.js';
const reactDomSrc = isProduction
? 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js'
: 'https://unpkg.com/react-dom@18/umd/react-dom.development.js';
function loadScript(src) {
return new Promise((resolve) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
document.head.appendChild(script);
});
}
Promise.all([loadScript(reactSrc), loadScript(reactDomSrc)])
.then(() => {
// React is now available globally as window.React
console.log('React version:', React.version);
// Initialize your application here
});
</script>
By loading the appropriate bundle at runtime, you maintain a single HTML file that automatically uses development builds with warnings on localhost and optimized production builds when deployed.
Key Source Files in the React Repository
The UMD bundles served by CDNs are built from the following source locations in the facebook/react repository:
packages/react/src/React.js– Defines the coreReactobject exported towindow.React, including hooks and component APIs.packages/react-dom/src/client/ReactDOM.js– Contains the client-side ReactDOM implementation, includingcreateRootandrendermethods that power the CDN globalReactDOM.packages/react/README.md– Documents the build targets and entry points for the core package.packages/react-dom/README.md– Documents the DOM-specific bundles and their usage patterns.scripts/release/README.md– Describes the release process that generates the UMD bundles published to npm and served by CDNs.
Summary
- React JS with CDN allows you to load the framework via UMD bundles without build tools, exposing
ReactandReactDOMas global objects onwindow. - The production builds (
react.production.min.js) are minified and stripped of warnings for optimal performance, while development builds (react.development.js) include verbose error messages. - According to the facebook/react source code, the global APIs originate from
packages/react/src/React.jsandpackages/react-dom/src/client/ReactDOM.js. - You can write JSX in the browser by adding the Babel standalone CDN, which compiles JSX to
React.createElementcalls at runtime. - For production deployments, use Subresource Integrity (SRI) hashes and load minified bundles; for local development, switch to development builds to access React's warning system.
Frequently Asked Questions
Can you use React with CDN in production?
Yes, the production UMD bundles served from unpkg are specifically built for production use. These files (react.production.min.js and react-dom.production.min.js) are minified, optimized, and have all development warnings stripped out. According to the facebook/react repository, these bundles are generated from the same source files (packages/react/src/React.js and packages/react-dom/src/client/ReactDOM.js) as the npm packages, ensuring API parity and stability.
How do you enable JSX when using React via CDN?
To use JSX syntax without a build step, include the Babel standalone CDN (@babel/standalone) alongside your React scripts. Mark your application script with type="text/babel" so the Babel compiler processes it before execution. Babel transforms JSX elements into React.createElement calls that reference the global React object loaded from the CDN. This approach is ideal for learning environments and quick prototypes, though the runtime compilation overhead makes it unsuitable for high-performance production applications.
What is the difference between React development and production CDN builds?
The development build (react.development.js) includes the full warning system and error messages that help identify common mistakes, such as invalid hook usage or deprecated patterns. These bundles are larger and execute slower due to the additional debugging code. The production build (react.production.min.js) strips all warnings and minifies the code for optimal download and execution speed. As implemented in the facebook/react source, the development build provides verbose console output while the production build focuses purely on runtime performance.
Which global objects does React CDN expose?
When loaded via CDN, React attaches two primary objects to the window global: window.React and window.ReactDOM. The React object contains the core API including createElement, useState, useEffect, and Component, as defined in packages/react/src/React.js. The ReactDOM object provides the client-side rendering API including createRoot and render, implemented in packages/react-dom/src/client/ReactDOM.js. These globals allow you to write React applications using standard script tags without ES6 imports or module bundlers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s https://instagit.com/install.md