DEV Community

Michael Smith
Michael Smith

Posted on

Ditching React for HTMX: A 2023 Migration Guide

Ditching React for HTMX: A 2023 Migration Guide

Meta Description: Discover how removing React.js from the codebase and adapting HTMX for UI interactivity in 2023 can simplify your stack and boost performance. Real-world guide inside.


TL;DR

In 2023, a growing number of development teams began questioning whether React.js was the right tool for every project. HTMX emerged as a compelling alternative — a lightweight library that lets you access modern browser features directly from HTML. This guide covers the why, the how, and the what to watch out for when migrating from React to HTMX, with practical steps you can act on today.


Key Takeaways

  • HTMX is not a React replacement for every project — it excels in server-rendered, content-heavy apps but struggles with highly stateful UIs
  • Removing React can reduce JavaScript bundle sizes by 85-95% in many real-world cases
  • The migration works best when paired with a strong server-side framework (Django, Rails, Laravel, Go, etc.)
  • HTMX's learning curve is significantly lower than React's ecosystem
  • You don't have to go all-in — a hybrid approach is valid during transition
  • Performance gains are real, but architectural discipline is required

Why Teams Started Removing React.js in 2023

React has dominated frontend development since roughly 2015. It's powerful, well-supported, and backed by Meta. So why were engineering teams in 2023 actively removing it from their codebases?

The honest answer: React solves problems that many apps don't actually have.

The JavaScript Fatigue Problem

By 2023, a typical React application came bundled with:

  • React + ReactDOM (~130KB minified)
  • A state management library (Redux, Zustand, Jotai — pick your poison)
  • A routing library (React Router, TanStack Router)
  • A data-fetching layer (React Query, SWR, Apollo)
  • Build tooling (Webpack, Vite, Babel)

For a content-heavy website, a marketing platform, or a traditional CRUD application, this is a staggering amount of complexity. You're shipping hundreds of kilobytes of JavaScript to render what is, fundamentally, HTML.

The "It Depends" Moment

The 2023 conversation was catalyzed by several high-profile posts and case studies — including the widely-cited GitHub blog post about their own JavaScript reduction efforts, and DHH's vocal advocacy for "The HTML Over The Wire" approach with Hotwire (a conceptual cousin to HTMX).

Teams started asking a simple but powerful question: "Do we actually need a client-side SPA here?"

For many, the honest answer was no.

[INTERNAL_LINK: When to use a SPA vs server-rendered architecture]


What Is HTMX and Why Does It Matter?

HTMX is a small (~14KB minified and gzipped) JavaScript library created by Carson Gross. Its core philosophy is radical: HTML should be the hypermedia of the web, not just a rendering target for JavaScript.

With HTMX, you extend HTML with custom attributes that enable:

  • AJAX requests on any element (not just forms and links)
  • CSS transitions
  • WebSockets and Server-Sent Events
  • Partial page updates without a full page reload

Here's a concrete example. In React, a simple button that fetches and displays data might look like this:

function UserCard() {
  const [user, setUser] = useState(null);

  const fetchUser = async () => {
    const res = await fetch('/api/user/1');
    const data = await res.json();
    setUser(data);
  };

  return (
    <div>
      <button onClick={fetchUser}>Load User</button>
      {user && <div>{user.name}</div>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In HTMX, the equivalent looks like this:

<button hx-get="/user/1" hx-target="#user-card" hx-swap="innerHTML">
  Load User
</button>
<div id="user-card"></div>
Enter fullscreen mode Exit fullscreen mode

Your server returns an HTML fragment — not JSON — and HTMX drops it into the target element. No JavaScript written by you. No state management. No build step.


React vs. HTMX: An Honest Comparison

Feature React HTMX
Bundle size ~130KB+ (+ dependencies) ~14KB
Learning curve High (JSX, hooks, state, effects) Low (HTML attributes)
Build tooling required Yes (Vite, Webpack) No
State management Complex (useState, Redux, etc.) Server-side
SEO out of the box Poor (needs SSR/Next.js) Excellent
Real-time features Good (with libraries) Good (SSE, WebSockets)
Complex UI interactions Excellent Limited
Team onboarding time Days to weeks Hours
Ecosystem maturity Massive Growing
Best for SPAs, complex UIs Content sites, CRUD apps

The honest verdict: React wins for complex, stateful UIs. HTMX wins for everything else — and "everything else" is a larger category than most developers admit.


When Removing React Makes Sense (And When It Doesn't)

Good Candidates for HTMX Migration

  • Marketing websites and landing pages — content rarely changes based on client state
  • Admin dashboards — mostly forms, tables, and data display
  • E-commerce product listings — server-rendered with filtered searches
  • Blog platforms and CMS frontends — almost entirely server-driven
  • SaaS applications with standard CRUD — create, read, update, delete doesn't need a SPA
  • Internal tools — where developer experience matters more than bundle size

Poor Candidates for HTMX Migration

  • Figma-like design tools — massive client-side state, canvas manipulation
  • Real-time collaborative editors — Google Docs style
  • Complex data visualization dashboards — where D3.js or Recharts are doing heavy lifting
  • Games or interactive simulations
  • Offline-first PWAs — where client-side state is the point

[INTERNAL_LINK: Choosing the right frontend architecture for your SaaS]


Step-by-Step: How to Migrate from React to HTMX

Step 1: Audit Your React Components

Before touching any code, map your existing React components by complexity:

  • Simple components (static rendering, minimal state): Migrate first
  • Medium components (one or two useState hooks, basic fetching): Migrate second
  • Complex components (heavy state, context, third-party integrations): Migrate last or keep in React

Tools like Webpack Bundle Analyzer can help you understand exactly what's contributing to your bundle size before you start.

Step 2: Choose Your Server-Side Framework

HTMX is server-agnostic, but it works best when your server can return HTML fragments efficiently. Strong pairings include:

  • Python: Django with django-htmx (a fantastic, well-maintained extension)
  • Ruby: Rails with Hotwire/Turbo (conceptually similar)
  • PHP: Laravel with Livewire or raw HTMX
  • Go: Templ or standard html/template
  • Node.js: Express with EJS or Pug templates
  • Java: Spring Boot with Thymeleaf

The key requirement: your server needs to return HTML, not JSON. This is a mental model shift for teams used to building REST APIs for frontend consumption.

Step 3: Set Up HTMX

Installation is almost embarrassingly simple compared to a React setup:

<script src="https://unpkg.com/htmx.org@1.9.6"></script>
Enter fullscreen mode Exit fullscreen mode

Or via npm if you prefer:

npm install htmx.org
Enter fullscreen mode Exit fullscreen mode

No Babel. No JSX transform. No webpack config. That's it.

Step 4: Migrate Components Incrementally

Don't attempt a big-bang migration. Instead:

  1. Identify one isolated feature — a search bar, a data table, a modal
  2. Create the server endpoint that returns an HTML fragment
  3. Replace the React component with HTMX-powered HTML
  4. Test thoroughly, especially edge cases (loading states, errors, empty states)
  5. Repeat

HTMX and React can coexist in the same page during migration. React components can be rendered server-side and then HTMX can handle subsequent interactions.

Step 5: Handle Common React Patterns in HTMX

Loading states:

<button hx-get="/data" hx-indicator="#spinner">
  Load Data
</button>
<div id="spinner" class="htmx-indicator">Loading...</div>
Enter fullscreen mode Exit fullscreen mode

Form validation:

<form hx-post="/submit" hx-target="#result" hx-swap="outerHTML">
  <input name="email" type="email" required>
  <button type="submit">Submit</button>
</form>
<div id="result"></div>
Enter fullscreen mode Exit fullscreen mode

Polling for updates:

<div hx-get="/notifications" hx-trigger="every 5s" hx-swap="innerHTML">
</div>
Enter fullscreen mode Exit fullscreen mode

Step 6: Remove React Dependencies

Once you've migrated all components, you can remove React from your project:

npm uninstall react react-dom @types/react @types/react-dom
Enter fullscreen mode Exit fullscreen mode

Then remove any React-specific build configuration from your bundler. If your entire frontend is now HTMX, you may not need a JavaScript build step at all.


Real-World Results: What Teams Reported in 2023

Several teams documented their migrations publicly in 2023. Common outcomes included:

  • Bundle size reduction: 85-95% smaller JavaScript payloads
  • Time to Interactive (TTI): 40-60% improvement on median connections
  • Developer onboarding: New developers productive in hours, not days
  • Server load: Slight increase (server now renders HTML, not just JSON), but offset by CDN caching of HTML fragments
  • Lighthouse scores: Significant improvements in Performance and Best Practices categories

One particularly notable case: a SaaS team running a project management tool reported reducing their JavaScript bundle from 1.2MB to 67KB after migrating their dashboard from React to HTMX + Django. Their Lighthouse performance score jumped from 54 to 91.

[INTERNAL_LINK: Web performance metrics that actually matter in 2024]


Tools and Libraries to Support Your Migration

For Development

  • VS Code HTMX Extension — Provides IntelliSense for HTMX attributes, genuinely useful
  • htmx-debugger — A browser extension for debugging HTMX requests
  • Browser DevTools — Honestly, you need far less specialized tooling with HTMX

For Styling (Since You're Ditching the React Component Model)

  • Tailwind CSS — Works beautifully with server-rendered HTML fragments; highly recommended
  • Alpine.js — A lightweight JavaScript library for client-side interactions HTMX doesn't handle (dropdowns, toggles); pairs well with HTMX

For Testing

  • Playwright — End-to-end testing works the same regardless of whether you're using React or HTMX
  • Django Test Client / Rails system tests — Server-side testing becomes more important and more straightforward

Common Pitfalls and How to Avoid Them

Pitfall 1: Trying to Replicate React's Mental Model

HTMX requires a different way of thinking. You're not managing state on the client — the server is the source of truth. Developers who try to recreate React patterns in HTMX will struggle. Embrace the server-centric model.

Pitfall 2: Ignoring Alpine.js for Client-Only State

Some UI interactions are genuinely client-side: dropdown menus, modal toggles, tab switching. HTMX doesn't handle these elegantly. Alpine.js (2KB) fills this gap perfectly and is designed to work alongside HTMX.

Pitfall 3: Forgetting About CSRF Protection

When HTMX sends POST requests, you need CSRF tokens. Most server frameworks handle this, but you need to configure HTMX to include the token:

document.body.addEventListener('htmx:configRequest', (event) => {
  event.detail.headers['X-CSRFToken'] = getCookie('csrftoken');
});
Enter fullscreen mode Exit fullscreen mode

Pitfall 4: Underestimating Server-Side Template Complexity

Your server-side templates will become more complex as they handle more rendering logic. Invest in a solid templating system and component-like template includes/partials.


The Honest Bottom Line

Removing React.js from the codebase and adapting HTMX for UI interactivity in 2023 was not a trend — it was a correction. The JavaScript ecosystem had drifted toward complexity as a default, and HTMX represented a legitimate architectural alternative for a large class of web applications.

Is HTMX right for your project? Ask yourself honestly: "Is my application's complexity driven by genuine UI requirements, or by the framework I chose?"

If the answer is the latter, HTMX deserves serious consideration.


Start Your Migration Today

Ready to simplify your stack? Start small: pick one React component in your codebase — ideally a data-fetching one with minimal client state — and rebuild it with HTMX. You'll understand within an afternoon whether this approach fits your project.

For deeper learning, the HTMX official documentation is genuinely excellent and readable. The book Hypermedia Systems by Carson Gross (available free online) provides the philosophical foundation that makes HTMX click conceptually.

Have you migrated from React to HTMX? Share your experience in the comments below.


Frequently Asked Questions

1. Is HTMX production-ready for serious applications?

Yes. HTMX is used in production by companies ranging from startups to established SaaS businesses. It's been stable since version 1.0 and version 2.0 was released in 2024 with additional improvements. The library is intentionally small and focused, which contributes to its stability.

2. Can I use HTMX and React in the same application?

Absolutely. During migration, this is common and practical. You can have HTMX handling some routes/features while React handles others. The two libraries don't conflict. Long-term, maintaining both adds complexity, so plan to converge on one approach.

3. Does HTMX work with Next.js or other React meta-frameworks?

Technically yes, but it's an awkward pairing. If you're using Next.js for SSR and want to move away from React, you'd typically move to a different server framework entirely (Django, Rails, Laravel, Go) rather than trying to use HTMX within the Next.js ecosystem.

4. What happens to SEO when I switch from React to HTMX?

SEO typically improves when moving from client-side React to HTMX. Since HTMX relies on server-rendered HTML, search engine crawlers see fully-rendered content immediately — no JavaScript execution required. If you were using React without SSR, the SEO improvement can be dramatic.

5. Is HTMX suitable for mobile web applications?

Yes, and it often performs better on mobile than heavy JavaScript SPAs. The smaller payload means faster load times on mobile networks. The main consideration is that HTMX requires network connectivity for interactions (since requests go to the server), which matters for offline-first requirements — but that's a use case where React with service workers would be more appropriate anyway.

Top comments (0)