After building applications with React, Vue, and recently with HTMX/FastHTML, I have a clear perspective on when to use each approach.

The Problem with SPAs

Don't get me wrong: React is excellent. But for many enterprise applications, a SPA introduces unnecessary complexity:

Typical SPA:
├── Frontend (React/Vue)
│   ├── State management (Redux/Vuex)
│   ├── Routing (React Router)
│   ├── API client (Axios/fetch)
│   ├── Build system (Webpack/Vite)
│   └── Testing (Jest/Cypress)
├── Backend (API)
│   ├── Serializers
│   ├── CORS config
│   └── Auth tokens
└── DevOps
    ├── 2 deployments
    └── 2 CI/CD pipelines

For an internal ERP or admin panel, this is overkill.

The HTMX Philosophy

HTMX proposes something radical: the server sends HTML, not JSON.

<!-- A button that updates only part of the page -->
<button
    hx-post="/add-product"
    hx-target="#cart"
    hx-swap="innerHTML">
    Add to cart
</button>

<div id="cart">
    <!-- Server sends HTML here -->
</div>

The server responds with ready-to-render HTML:

@rt('/add-product')
def post(product_id: int):
    cart = add_to_cart(product_id)
    # Returns HTML, not JSON
    return Div(
        *[CartItem(item) for item in cart.items],
        P(f'Total: ${cart.total}')
    )

Real Comparison

Aspect SPA (React) HTMX
Initial time 2-3 weeks 2-3 days
Lines of code 10,000+ 2,000
Dependencies 50+ 3-5
Bundle size 200KB+ 14KB
SEO Requires SSR Native
Caching Complex Standard HTTP

When to Choose HTMX

Ideal for: - Admin panels - ERPs and internal systems - Landing pages with interactivity - CRUD applications - Rapid MVPs

Examples from my projects: - ERP Market: Complete POS with HTMX - AgencyFlow: Multi-tenant CRM - Metalurgica: B2B site with forms

When to Choose SPA

Necessary for: - Offline-first apps - Complex editors (Figma, Notion) - Dashboards with heavy interactive charts - Hybrid mobile apps

Hybrid Pattern

Best of both worlds: HTMX for 90%, JavaScript islands for the complex parts.

<!-- HTMX for structure -->
<div hx-get="/dashboard" hx-trigger="load">
    Loading...
</div>

<!-- Alpine.js for local interactivity -->
<div x-data="{ open: false }">
    <button @click="open = !open">Menu</button>
    <nav x-show="open">...</nav>
</div>

<!-- Chart.js only where needed -->
<canvas id="chart"
    x-data
    x-init="renderChart($el, await fetch('/api/data').then(r => r.json()))">
</canvas>

My Current Stack

FastHTML + HTMX + Alpine.js
├── Server-side rendering (SEO, performance)
├── Partial updates (fluid UX)
├── Minimal JS (only where it adds value)
└── Single deployment (simplicity)

Conclusion

HTMX is not "going back to the past". It's recognizing that HTTP and HTML already solve 90% of UI problems, and that adding a JavaScript layer only makes sense when you really need it.

For my next enterprise project, HTMX will be my first choice. I'll reserve React for when I truly need a SPA.