Seongyeol Yi

Alternatives to React

I used to default to Next.js for side projects. But the more I used it, the less sure I was whether I was actually learning frontend development or just getting better at debugging Next.js. I realized I had never considered anything other than React or Next.js as a tech stack.

If you started learning frontend development in the 2020s, chances are you focused on React — probably because it’s the most widely used (i.e., most useful for getting hired) frontend tool.

But React isn’t the only option. Frontend development existed before React was released. Looking at the landscape now, over a decade later, State of JS surveys show plenty of developers frustrated with Next.js/React. Alternatives like Astro are gaining traction.

It was fine to take React for granted while studying and job hunting, but now is a good time to reflect on why we use it. Why don’t we just manipulate the DOM directly? Are there situations where React isn’t necessary?

DOM API Refresher

Before React, frontend development meant directly modifying the UI through the DOM API. If you wanted to increment a number when a button is clicked, you’d access the DOM element and change its content directly.

const buttonElement = document.getElementById("some-button-id");
const textElement = document.getElementById("some-text-id");

let count = 0;

function increment() {
  count++;
  textElement.textContent = count.toString();
}

buttonElement.addEventListener("click", increment);

Building a Shop with the DOM API

The code above makes direct DOM manipulation look fine. Let’s look at a more complex example. Using a shopping cart, we’ll see where the DOM API approach gets painful.

Initially, there’s a simple feature: clicking the cart button adds a product.

Products

Product A

Cart

Now imagine the requirements change: “If a product already in the cart is clicked again, its quantity increases, and if the quantity reaches 0, the item is removed.” The developer now has to figure out how to update the existing cart UI:

  • Adding a new product requires creating a new DOM element, but…
  • Changing a quantity requires finding the existing element and updating its text…
  • Removing a product requires fully removing the DOM element and cleaning up all event listeners attached to it.

Products

Photocard
Keyring
Sticker
Mug

Cart

  • Your cart is empty.

Even more complex situations arise. Imagine you’re building a feature where the product list refetches from the server every time the user changes a filter. Click the filters below quickly in order to trigger a race condition:

  1. Click “Price: Under $10” (takes 1.5s)
  2. Click “Color: Black” (takes 0.5s)

Product Filter

Products

  • Photocard - ₩5000 (Black)
  • Keyring - ₩15000 (Black)
  • Sticker - ₩4000 (White)
  • Mug - ₩12000 (White)

Notice how the radio button shows “color” selected, but the actual filter shows price results? The developer now has to figure out how to keep only the latest request. With the DOM API, this means tracking the state of each request, checking whether a response is for the latest request when it arrives, and manually managing which DOM elements map to which requests — a headache-inducing task.

DOM API Summary

One of the biggest challenges with the DOM API is deciding what to do with existing DOM elements when state changes. Developers must make complex decisions: should existing elements be completely removed and recreated, should they be reused with only content updated, which event listeners need to be removed and reattached, and how should animations or transitions be handled.

Enter React

React handles the job of rendering UI from state.

UI = f(state)

Developers only need to declare what UI should appear for each state — they don’t have to figure out how to command the DOM API to produce it. This is mentioned in the React docs:

React components receive data and return what should appear on the screen.

React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.

DOM API vs React

Compare the component below implemented with the DOM API versus React.

0

With the DOM API, you command step-by-step how (HOW) to make changes.

let count = 0;
const counter = document.getElementById("counter");

function increment() {
  count++;
  // Find and modify the DOM directly
  counter.textContent = count;
  // Manually change styles based on conditions
  if (count > 0) {
    counter.className = "positive";
  } else if (count < 0) {
    counter.className = "negative";
  } else {
    counter.className = "zero";
  }
}

const counterButton = document.getElementById("counter-button");
counterButton.addEventListener("click", increment);

With React, you simply declare what (WHAT) the UI should be based on state.

function Counter() {
  const [count, setCount] = useState(0);
  const className = (() => {
    if (count > 0) return "positive";
    if (count < 0) return "negative";
    return "zero";
  })();

  return (
    <div>
      <div className={className}>{count}</div>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

When Should You Use React?

React’s advantages are clear in applications with complex and frequent state changes. For example, in a shopping site like the examples above — with user login/logout, cart management, product filtering and sorting, and multiple states affecting each other — or when heavy user interaction causes frequent DOM updates, React dramatically reduces development complexity.

But for static pages with little state change — like company landing pages or blog posts — or websites with just simple form submissions, React can be overkill. In those cases it only adds to bundle size and initial load time.

Wrap-up

We’ve reflected on what problems React solves. Technology will keep evolving and new paradigms will emerge, but what matters is understanding the problem each tool solves and choosing the right one for the situation.

More on Frontend

View all posts