Building React Applications Without a Build Step or Framework: A Simple Approach

Building React Applications Without a Build Step or Framework: A Simple Approach
Photo by Andrik Langfield / Unsplash

In a world where modern web development often comes with complex build tools, package managers, and configuration files, some developers may feel overwhelmed by the number of steps needed to get started with React. What if you could bypass these build tools entirely and write React code directly in your HTML file, just like traditional scripting?

It’s possible! This approach might not be suited for large-scale projects, but it offers a clean and straightforward way to build small apps or experiment with React without the need for a full build process. Whether you're creating a quick prototype or teaching React, this method can be ideal.

Let's walk through a basic example where React, React Router, and JSX are all used without any build steps. You can simply open your HTML file in a browser and see your app running.

Final Code

If you are in rush mode, no worries, here is the GitHub repository about this topic, and also the demo website.

GitHub - sonyarianto/react-without-buildsteps: Oh boy, this skeleton project is dedicated to CDN fans around the world.
Oh boy, this skeleton project is dedicated to CDN fans around the world. - sonyarianto/react-without-buildsteps

If you want to read the explanation, just go on.

The Basic Setup

First, you need to include a few key libraries via CDN links directly in your HTML file. The core ones are React, ReactDOM, React Router, and Babel. Babel is particularly important here because we want to use JSX syntax, which allows us to write HTML-like syntax in our JavaScript. Browsers don’t natively understand JSX, so Babel transpiles it to regular JavaScript.

Here’s an example of a simple HTML file with these scripts included:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>React without build steps</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.production.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@remix-run/[email protected]/dist/router.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/react-router.production.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/react-router-dom.production.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@babel/[email protected]/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel" data-presets="env,react">
    // React code goes here
  </script>
</body>
</html>

In this file, we load the required libraries directly from CDNs, which makes it possible to start using React and React Router without any additional setup or configuration.

Writing React Components

Once the libraries are loaded, you can start writing React components right inside your <script type="text/babel"> tag. The data-presets="env,react" attribute ensures that Babel converts JSX into browser-friendly JavaScript.

For instance, you can create a simple Header component with navigation buttons and a Footer component to make your app more dynamic:

function Header() {
  const navigate = useNavigate();

  return (
    <header>
      <nav>
        <button onClick={() => navigate('/')}>Home</button>
        <button onClick={() => navigate('/about')}>About Us</button>
      </nav>
    </header>
  );
}

function Footer() {
  return <pre>View the source code to learn how this was built!</pre>;
}

Routing with React Router

React Router is one of the most commonly used libraries for navigation in React apps. Even without a build step, you can still use it seamlessly. You can set up routes using the createBrowserRouter function from React Router and define paths for each page.

Here’s an example of setting up routes for a simple two-page app:

const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/about', element: <About /> },
]);

function Home() {
  return (
    <div>
      <Header />
      <h1>Welcome to the Home Page!</h1>
      <Footer />
    </div>
  );
}

function About() {
  return (
    <div>
      <Header />
      <h1>About Us</h1>
      <Footer />
    </div>
  );
}

ReactDOM.render(<RouterProvider router={router} />, document.getElementById('root'));

Here, the app has two routes: the home page (/) and the about page (/about). Each page is represented by a component (Home and About), and the navigation between them is handled with React Router’s useNavigate hook.

Using JSX Without a Build Tool

Since JSX is not natively understood by the browser, Babel takes care of the transpilation on the fly. This is made possible by the <script type="text/babel"> tag. Although using Babel in the browser adds some performance overhead during development, it's a great way to start quickly, especially for small apps or learning purposes.

Advantages of Skipping Build Steps

One of the most immediate benefits of this approach is its simplicity. There's no need for complex build tools like Webpack, no package managers, no configuration files. You just write your HTML, include the necessary libraries, and get to coding. This is especially beneficial when:

  • You're building a prototype or proof-of-concept.
  • You want to demonstrate a simple example without overwhelming others with a complicated setup.
  • You want a lightweight environment for quick experimentation.

This setup also makes your app easy to share. The entire code is contained within a single HTML file, which can be copied, sent, or hosted with minimal effort.

Potential Limitations

While this no-build setup is convenient, there are certain limitations. Since all dependencies are loaded from external CDNs, the app relies on network availability and may be slower to load on first visit. Additionally, for larger applications, the lack of build tools like bundlers and compilers may lead to performance bottlenecks.

You also miss out on features like hot-reloading, TypeScript support, and advanced optimizations offered by tools like Vite or Next.js. These tools also help with code splitting and minification, which are key for production-ready applications.

Finally

Building React apps without a build step offers a refreshing simplicity for small-scale projects or learning purposes. It allows developers to focus on the core of React without worrying about toolchains, dependencies, or configurations. However, this approach does come with limitations, especially when scaling to larger projects or aiming for production-level performance.

If you’re just starting with React or need to create a quick prototype, this method can be an excellent way to dive in. For more complex applications, though, the conventional build tools might become essential to optimize and manage your code effectively.

Here is the code again

GitHub - sonyarianto/react-without-buildsteps: Oh boy, this skeleton project is dedicated to CDN fans around the world.
Oh boy, this skeleton project is dedicated to CDN fans around the world. - sonyarianto/react-without-buildsteps

Support Us

Subscribe to Buka Corner

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe