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>
);
}
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>
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>
Or via npm if you prefer:
npm install htmx.org
No Babel. No JSX transform. No webpack config. That's it.
Step 4: Migrate Components Incrementally
Don't attempt a big-bang migration. Instead:
- Identify one isolated feature — a search bar, a data table, a modal
- Create the server endpoint that returns an HTML fragment
- Replace the React component with HTMX-powered HTML
- Test thoroughly, especially edge cases (loading states, errors, empty states)
- 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>
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>
Polling for updates:
<div hx-get="/notifications" hx-trigger="every 5s" hx-swap="innerHTML">
</div>
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
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');
});
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)