Articles

Just Use React

Kent C. Dodds
Kent C. Dodds

JUST USE REACT

(OR ANY MODERN FRAMEWORK, ESPECIALLY FOR COMPLEX PROJECTS)


NOTE: This post is adapted from justf***ingusereact.com. The original uses strong language for humorous emphasis. That's really the whole point. That said, there are interesting points in the post so this version aims to convey the core message without profanity or rude language. I basically just gave the original to AI and asked it to make it nicer. I'm posting it here partly as a joke, and also because reading curse words hurts my head.

Credit to original creators is noted at the end.

With that said, let's get into it:


It's understandable. You might have seen discussions championing "pure HTML," "keeping it simple," or noting how "My GeoCities page from '98 still loads faster than your SPA." These are valid points in many contexts, and the desire for simplicity is commendable.

It's a nice sentiment, much like wishing for simpler economic systems. However, the web today often hosts more than just static informational pages. It's a platform for dynamic applications, collaborative workspaces, and rich interactive experiences. These often require a different set of tools and approaches than a "Very beautiful button" on a static page.

SO, WHAT'S THE POINT HERE?

The idea is to acknowledge that sometimes, complexity in a project isn't an arbitrary choice, but a genuine requirement of the features being built. When these complex requirements arise, trying to manage everything with direct DOM manipulation and standalone JavaScript files can become akin to building a sophisticated machine with only the most basic hand tools. You might achieve the goal, but the process can be challenging, and the result harder to maintain or scale.

This is an invitation to consider the powerful tools developed by many talented engineers. These tools are designed to handle common complexities, allowing development teams to focus on unique application logic and user experience, rather than repeatedly solving foundational problems.

WHY MIGHT ONE CONSIDER MOVING FROM "PURE HTML" TO JAVASCRIPT FRAMEWORKS?

Because often, the goal is to build more than a static document. You're looking to create something interactive, dynamic, and user-friendly—an application that offers a rich experience, not just a digital flyer.

Here's why using React (or Vue, Svelte, Angular, or a similar modern framework) can be beneficial, especially as project complexity grows:

HTML'S BUILT-IN INTERACTIVITY IS A GREAT STARTING POINT, BUT MAY NOT SUFFICE FOR RICH APPLICATIONS.

"But HTML has <details>, <dialog>, and forms!" Absolutely, and these are fantastic for many use cases. They are essential building blocks. However, are they always sufficient for a real-time collaborative editor, a dynamic trading dashboard, or an enterprise-grade project management tool?

When building such applications, the native interactive elements of HTML, even with vanilla JavaScript, might require a significant amount of custom code to orchestrate complex user workflows and manage state. What HTML provides are the fundamental elements; frameworks often provide the structure and machinery to build more elaborate systems on top of those fundamentals.

EFFECTIVE STATE MANAGEMENT IS KEY.

Managing the state of a simple "like" button by toggling a class is straightforward. But consider a dashboard with multiple filters, real-time data from various sources, user-specific preferences, and perhaps even collaborative editing features. A "simple" JavaScript approach here can quickly lead to a tangled web of interconnected logic that's difficult to debug and maintain. Frameworks offer structured and often more intuitive ways to manage this kind of application state. Without them, developers might find themselves navigating a tricky path, hoping to avoid global variable conflicts or hard-to-trace bugs.

The interactive demo on the original site provides a good visual for this point!

COMPONENTS: BUILD ONCE, USE EVERYWHERE.

Remember the times you might have copied and pasted HTML for a navigation bar across many pages, only to update each instance when a new link was needed? It's a common early approach, and understandable at the time.

Frameworks like React encourage (or enforce) thinking in terms of reusable, encapsulated components. A button, a form field, or an entire user profile card can be built once—its structure, style, and logic defined in one place—and then reused wherever needed. A change in the component's definition updates it everywhere. This isn't just about convenience; it's about maintainability, consistency, and sanity, especially as applications grow or are worked on by teams.

SMARTER, MORE EFFICIENT UI UPDATES.

Manually updating many parts of a page when a single piece of data changes can be error-prone. One might find themselves meticulously telling each <span> and <div> to refresh, hoping not to miss anything or cause inefficient re-renders of the entire page.

Frameworks are designed to be intelligent about UI updates. You declare what the UI should look like based on the current data (state). When that data changes, the framework efficiently determines the minimal set of changes needed in the actual DOM. It's like having a highly optimized assistant that only repaints the necessary parts, rather than redecorating the whole house when one picture is moved. This declarative approach often leads to cleaner code and better performance.

ACCESSIBILITY AT SCALE: A STRUCTURED APPROACH.

"Just use semantic HTML!" is excellent advice and a cornerstone of web development. That's Web Dev 101.

But what about complex, custom UI elements that go beyond standard HTML tags? Consider custom data grids with sorting and filtering, accessible comboboxes with type-ahead features, or navigable tree views. Simply adding role="button" to a <div> is a start, but true accessibility for such components involves careful management of ARIA attributes, focus, and keyboard interactions. Implementing this correctly and consistently across many instances with vanilla JavaScript can be a significant undertaking.

Frameworks allow you to build an accessible component once, encapsulating all the necessary ARIA attributes and behaviors. This component can then be reused, promoting consistency and making it easier to maintain high accessibility standards. Would one prefer to manually manage aria-expanded and related states on 50 different accordion instances, or define it once in a reusable component? For complex UIs, relying solely on basic HTML can sometimes inadvertently lead to experiences that aren't fully accessible to all users.

THE "SIMPLE" HTML FAÇADE CAN SOMETIMES HIDE A LOT OF MANUAL JAVASCRIPT WORK.

Phrases like "No hydration errors! No tree-shaking!" might sound appealing, framing these as complexities to be avoided. However, these are often sophisticated solutions to real problems that arise when building substantial client-side applications.

Opting out of a framework doesn't make these problems disappear if the application's requirements inherently involve them. It often means that the developer or team is now responsible for manually implementing solutions for DOM diffing, state propagation, code splitting for performance, and other optimizations—tasks that frameworks have evolved to handle effectively. It's not always about choosing "simplicity" over "complexity," but rather choosing to leverage well-tested solutions for common complex problems, or to build those solutions from scratch. The latter can be like choosing to manually craft every part of a complex machine when pre-fabricated, optimized components are readily available.

RELYING ON HTML'S ID-BASED GLOBAL JAVASCRIPT VARIABLES: A HISTORICAL CURIOSITY.

It's true that HTML elements with id attributes can sometimes become global JavaScript variables. This was a "feature" from an earlier era of the web. Relying on this today can be risky.

It can pollute the global namespace, lead to hard-to-debug naming collisions, and contribute to a fragile, less maintainable codebase. This can cause significant frustration for future developers (including your future self!).

Frameworks guide developers towards more robust patterns: scoped components, explicit data flow (like props), and dedicated state management solutions that don't depend on the chance that window.myButton hasn't been overwritten. This isn't HTML "lending crutches"; it's frameworks helping to avoid potential pitfalls inherent in some older browser behaviors.

DEVELOPER EXPERIENCE (DX) MATTERS FOR PRODUCTIVITY AND ENJOYMENT.

Consider features like Hot Module Replacement (seeing UI changes instantly without losing application state during development), the safety net of TypeScript, a vast ecosystem of libraries for tasks from internationalization to animation, and robust linters, formatters, and debuggers.

Frameworks, especially mature ones like React, come with an ecosystem that can make the development process more productive and enjoyable. This often translates to building better applications, faster. Pretending that grappling with browser inconsistencies and older JavaScript patterns is inherently more virtuous can be a less efficient path for complex projects.

PERFORMANCE IS MORE THAN JUST INITIAL LOAD; IT'S ABOUT THE ENTIRE USER EXPERIENCE.

"My HTML site loads in 50ms!" That's great for initial delivery. But what happens when you add user login, dynamic content fetching, client-side filtering and sorting, and real-time updates without causing the page to become unresponsive or slow?

Frameworks, particularly when combined with their meta-frameworks (like Next.js or Remix for React), provide tools for a holistic approach to performance. This includes code-splitting (loading only necessary JavaScript), server-side rendering (SSR) or static site generation (SSG) for fast initial loads combined with dynamic capabilities, and smooth client-side navigation. The goal is to build a high-performance application, not just a document that loads quickly but offers limited interactivity.

BUT WHAT ABOUT THE "BLOAT"? THE JAVASCRIPT OVERHEAD?

It's true: a "Hello World" application in a framework will likely have a larger initial JavaScript footprint than a plain HTML "Hello World." That's to be expected. But are most production applications "Hello World" simple? If you're building a very simple, mostly static, five-page brochure website, then yes, HTML and CSS are likely perfectly sufficient and the most efficient choice. The "other site" makes a good point here. One doesn't need a bulldozer to plant a flower.

However, if the project involves:

  • A SaaS platform
  • An e-commerce site with a complex shopping cart and user accounts
  • A dynamic social media feed
  • A feature-rich project management tool
  • An interactive data visualization dashboard
  • Anything with significant client-side interactivity and state that needs to function reliably and be maintainable

...then the initial JavaScript "cost" of a framework can be seen as an investment in the infrastructure needed to build and manage that complexity. Modern tools like tree-shaking, code-splitting, and lazy loading help significantly in mitigating this cost. It's about selecting the appropriate tool for the task, rather than sticking to a familiar tool when a more specialized one would be more effective for the scale of the project.

SO, WHEN MIGHT IT BE A GOOD IDEA TO USE REACT (OR A SIMILAR FRAMEWORK)?

Consider a modern framework when:

  • Your application has non-trivial client-side state that needs to be managed effectively.
  • You need reusable UI components to build a consistent, maintainable, and scalable interface.
  • You're developing a Single Page Application (SPA) or an application that aims for a fluid, app-like experience rather than a series of document loads.
  • You're working in a team and need shared structures, patterns, and a common vocabulary.
  • The complexity of user interactions would likely lead to difficult-to-manage "spaghetti code" if built with vanilla JavaScript alone.
  • You want to leverage a rich ecosystem of well-tested libraries, tools, and community support.
  • Developer velocity and the ability to efficiently build complex features are more critical than minimizing every last kilobyte for a largely static page.

THE REAL CHALLENGE ISN'T THE FRAMEWORK ITSELF, BUT HOW WE CHOOSE AND USE OUR TOOLS.

The challenge often lies in selecting the right tool for the job. Sometimes, a simpler solution is indeed best. Developers might occasionally use an overpowered tool for a simple task, or adopt new technologies without fully evaluating their fit for the problem at hand. It can be like using a high-powered industrial tool for a delicate home repair—perhaps overkill.

However, let's not dismiss powerful tools simply because they can be misapplied. React and similar frameworks are capable tools that solve real, complex problems effectively. The issue isn't usually the tool itself, but ensuring it's wielded appropriately for the task.

So, for your next complex, interactive, data-driven web application, CONSIDER USING REACT (OR A SIMILAR FRAMEWORK). It's not about purity, but about pragmatism and choosing tools that can help you and your team build robust, maintainable applications. Your users (and your future self, tasked with maintaining the codebase) will likely appreciate the structure and capabilities these frameworks provide.

Now, go forth and build something amazing, leveraging the best tools for your specific challenges, rather than creating an HTML solution that might not scale with your ambitions.


This content is adapted from justf***ingusereact.com to present its arguments in a different tone. Original credit to its creators.

Original Creators:

Omercan (GitHub / X / Bluesky)

Burak (GitHub / X / Bluesky)

Inspired by justf***ingusehtml.com

View the source code of the original on GitHub

Get my free 7-part email course on React!

Delivered straight to your inbox.