Front-End · 9 min read · Updated

React vs Plain JavaScript: When Do You Actually Need React?

Not every website needs React. Compare the same feature in plain JavaScript and React 19, and use a simple checklist to decide which one a project needs.

React vs vanilla javascript: developer Discuss
Photo: Christina Morillo via Stocksnap (CC0)

Search for any front-end job and React appears everywhere. That makes many beginners assume every website must be built with it. It does not. React is excellent at one particular kind of problem – interfaces with a lot of changing state – and unnecessary for many others. Knowing the difference makes you a better developer and saves your clients from slow, over-engineered sites.

In this React vs vanilla JavaScript comparison, “vanilla” or “plain” JavaScript means the language and browser APIs on their own: querySelector, addEventListener, fetch and friends. React means the React 19 library, which is current in October 2026.

What plain JavaScript gives you

Modern browsers are far more capable than they were when libraries like jQuery became popular. With no extra downloads you get:

  • Fast DOM selection with querySelector and querySelectorAll.
  • Events with addEventListener, including event delegation on a parent element.
  • Network requests with fetch and async/await.
  • Native modules with <script type="module"> and import.
  • Built-in elements that used to need JavaScript: <dialog>, <details>, form validation and the popover attribute.

If those terms are new, start with DOM manipulation, events and fetch and async, or read JavaScript DOM Basics for Designers.

What React adds

React does not give the browser new powers. It gives you a different way to organise code:

  • Components. You split the UI into reusable functions such as <ProductCard /> and <CartSummary />, each with its own markup and logic.
  • Declarative rendering. You describe what the screen should look like for the current data, and React works out which DOM nodes to change. You stop writing “find this element, update its text, hide that one”.
  • State management built in. Hooks like useState keep data and UI in sync. When state changes, React re-renders the parts that depend on it.
  • A large ecosystem. Routing, forms, data fetching, testing and full-stack frameworks are built around it.
  • React 19 features such as Actions and useActionState for form submissions, useOptimistic for instant feedback, and ref as a normal prop.

The same feature, built both ways

Let us build a small city filter: type in a box, and the list shows matching cities with a count. First in plain JavaScript:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vanilla JS filter</title>
<style>
  body { font-family: system-ui, sans-serif; margin: 20px; }
  input { padding: 8px; width: 240px; }
  li { padding: 4px 0; }
</style>
</head>
<body>
  <label for="q">Search cities</label><br>
  <input id="q" type="search" placeholder="e.g. ma">
  <p id="count"></p>
  <ul id="list"></ul>
<script>
  const cities = ['Chennai', 'Madurai', 'Mysuru', 'Kochi', 'Mangaluru', 'Puducherry', 'Coimbatore'];
  const input = document.getElementById('q');
  const list = document.getElementById('list');
  const count = document.getElementById('count');

  function render() {
    const term = input.value.trim().toLowerCase();
    const matches = cities.filter(c => c.toLowerCase().includes(term));
    list.innerHTML = '';
    for (const city of matches) {
      const li = document.createElement('li');
      li.textContent = city;
      list.appendChild(li);
    }
    count.textContent = matches.length + ' of ' + cities.length + ' cities';
  }

  input.addEventListener('input', render);
  render();
</script>
</body>
</html>

Now the same thing in React 19. This browser-only setup with in-browser Babel is for learning; real projects use a build tool, as shown in Building a React project with Vite.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>React filter</title>
<script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<style>
  body { font-family: system-ui, sans-serif; margin: 20px; }
  input { padding: 8px; width: 240px; }
  li { padding: 4px 0; }
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel" data-type="module">
import React, { useState } from "https://esm.sh/[email protected]";
import { createRoot } from "https://esm.sh/[email protected]/client";

const cities = ['Chennai', 'Madurai', 'Mysuru', 'Kochi', 'Mangaluru', 'Puducherry', 'Coimbatore'];

function CityFilter() {
  const [term, setTerm] = useState('');
  const matches = cities.filter(c => c.toLowerCase().includes(term.trim().toLowerCase()));

  return (
    <>
      <label htmlFor="q">Search cities</label><br />
      <input id="q" type="search" placeholder="e.g. ma" value={term} onChange={e => setTerm(e.target.value)} />
      <p>{matches.length} of {cities.length} cities</p>
      <ul>
        {matches.map(city => <li key={city}>{city}</li>)}
      </ul>
    </>
  );
}

createRoot(document.getElementById('root')).render(<CityFilter />);
</script>
</body>
</html>

Both work. Look at what differs:

  • In plain JavaScript you write a render() function that clears and rebuilds the list by hand, and you must remember to call it after every change.
  • In React you only describe the output for a given term. When setTerm runs, React re-renders and updates the DOM for you.
  • The React version needs a library download and, in a real project, a build step. The plain version runs as it is.

For one search box, the plain version is perfectly fine. The difference shows when you add a cart, filters by price and state, a wishlist, a login status and a basket count in the header – all depending on each other. Keeping all of that in sync by hand is where bugs creep in, and that is the problem React was designed for.

The real costs of React

React is free to use, but it is not free in other ways:

  • JavaScript sent to users. React and React DOM must download and run before a client-rendered page is interactive. On budget Android phones and patchy mobile data, that cost is real. See Core Web Vitals for Designers.
  • Tooling. JSX needs compiling, so you need Node.js, a bundler such as Vite, and a basic understanding of npm.
  • Rendering choices. A purely client-side React app sends a nearly empty HTML page first. The official react.dev guide now recommends starting new apps with a framework such as Next.js or React Router, which can render on the server, and mentions Vite, Parcel or Rsbuild if you want to start from scratch.
  • Learning curve. State, props, effects, keys and the rules of hooks take time. You also need solid JavaScript first – arrays, objects, functions and modules.
  • Maintenance. Libraries around React update often, and an app has more dependencies to keep current.

React vs vanilla JavaScript: a checklist

Your projectPlain JavaScriptReact
Brochure site, portfolio, blogBest fit – mostly HTML and CSS with small scriptsUsually overkill
WordPress theme with a few interactive partsBest fitOnly for complex blocks in the editor
A form with validation and a success messageBest fitFine if the rest of the site is already React
Dashboard with filters, charts and live updatesPossible but grows messyGood fit
Booking flow with many steps and shared statePossible with careful structureGood fit
Web app used daily by logged-in usersHard to keep organisedGood fit
Team of several developers sharing componentsNeeds strong conventionsGood fit – components give structure

A quick rule of thumb: if most pages are content that people read, start with HTML, CSS and a little JavaScript. If most screens are tools that people use, with data changing in many places at once, React (or a similar library) earns its place.

Questions to ask before choosing

Before you run npm create vite@latest, answer these honestly. They matter more than which tool is trending.

  1. Who updates the content? If editors update pages in WordPress or another CMS, a React front end adds a layer between them and the page. Plain templates may serve them better.
  2. How much of the page changes after it loads? If the answer is “a menu and a form”, plain JavaScript is enough. If it is “almost everything, all the time”, consider React.
  3. Who will maintain it? A small business with no developer on staff is better served by simple HTML, CSS and a little JavaScript that any web developer can pick up.
  4. What devices do your users have? Test on a mid-range phone on mobile data, not only on your laptop. Less JavaScript usually means a faster first load.
  5. Does the team already know React? Consistency across projects has real value. A team fluent in React may build even simple tools faster with it.

Middle-ground options

  • Progressive enhancement. Build pages that work as plain HTML, then add JavaScript for nicer behaviour. Even inside a React framework this mindset helps.
  • Islands. Keep most of the page static and mount React only on one interactive widget, such as a product configurator. createRoot works on any element, not just a full-page #root.
  • Web Components. Custom elements are built into the browser and work with any framework or none. React 19 added full support for custom elements.
  • Small, well-structured modules. Plenty of interactive sites run on organised vanilla JavaScript split into ES modules.
  1. Learn JavaScript properly: arrays, objects, functions and modern ES6+ features. Keep the array methods cheat sheet handy – React code uses map and filter constantly.
  2. Build two or three small projects with plain JavaScript and the DOM, so you feel the pain React solves.
  3. Then follow the React track: components, props, state and lists and keys.
  4. Prepare for interviews with React Interview Questions for Freshers.

Tip: Interviewers often ask “why React?” A strong answer explains the problem it solves – keeping UI in sync with changing state – and admits when it is not needed. That shows judgement, not just syntax.

Common mistakes

  • Starting React before understanding functions, arrow functions, destructuring and map. Most “React problems” beginners face are JavaScript problems.
  • Building a five-page marketing site as a client-only React app, then wondering why it loads slowly.
  • Reaching into the DOM with document.querySelector inside React components instead of using state or refs.
  • Adding jQuery to a React app to change elements React controls – the two will fight over the same DOM. If you are curious about jQuery’s place today, read Is jQuery Still Worth Learning?

React vs vanilla JavaScript is not really a rivalry. React is JavaScript, organised in a particular way. Learn the language first, then choose the amount of structure each project actually needs.

Frequently asked questions

Should I learn JavaScript before React?

Yes. React uses ordinary JavaScript for logic: functions, arrays, objects, modules and array methods like map and filter. Without that foundation, React errors are very hard to understand.

Is React a framework or a library?

React describes itself as a library for building user interfaces. Frameworks such as Next.js and React Router add routing, data loading and server rendering on top of it.

Is plain JavaScript faster than React?

For small pages, plain JavaScript usually loads faster because there is no library to download and start. For large apps, a well-built React app can perform well, but performance depends far more on how you build than on which tool you pick.

Can I use React on just one part of a page?

Yes. createRoot can be called on any element, so you can mount a React widget inside an otherwise static page or a WordPress theme.

Do I need Create React App to start?

No. The current react.dev guide recommends starting with a framework such as Next.js or React Router, or using a build tool like Vite if you want to set things up yourself.

Further reading

Keep reading

All articles