Removing React.js from the codebase and adapting Htmx for UI interactivity (2023)
Transitioning from React.js to HTMX for UI Interactivity (2023)
Author: rafalp (Project Lead)
Date: December 2023 (with updates through July 2024)
Category: Roadmap / Misago Forums
🚩 The Current Architecture
Currently, the Misago request lifecycle follows a redundant path. When a user visits https://misago-project.org, the following sequence occurs:
- Server Side: A Django view renders a template. This template contains nearly complete HTML (e.g., a list of threads) but also embeds a JSON payload containing the same data.
- Client Side: JavaScript executes, parses the embedded JSON, and uses React.js components to overwrite the Django-rendered HTML.
📉 The Problem Space
This "double-rendering" approach creates several systemic inefficiencies:
- Redundancy: Many pages are developed twice—once as a Django template and once as a React component.
- Developer Friction: Customizers often edit Django templates only to see their changes flash briefly before React replaces them with different HTML.
- Route Duplication: Every public-facing view requires both a Django view/template and a React route/component.
- Performance Overhead:
- Generating JSON serializers for React slows down the initial server response.
- Heavy JavaScript bundles degrade performance, particularly on legacy mobile hardware.
- Localization Bloat: Translation strings are duplicated across
django.poanddjangojs.po, increasing the initial download size. - Plugin Complexity: Plugin developers must implement both Django and React versions of their UI injections.
- Build Pipeline: The
misago-dockersetup requires a complex JavaScript build step.
🛠 Evaluating Alternatives
The project lead considered two primary paths before settling on the final decision:
Pure SPA:Abandon Django templates entirely (keeping only minimal versions for SEO) and move all UI to a React app powered by an API.Modern SSR:Convert Django into a pure API and utilize a JavaScript framework with Server-Side Rendering (SSR).
The "Aha!" Moment: Why HTMX?
Most forum interactivity is not global; it is isolated to specific "islands" of functionality, such as:
- Poll voting
- Thread watching/notifications
- Moderation tools
- Replying to posts
These features don't require a full-blown framework. HTMX allows developers to define these "dynamic islands" that can be swapped with new server-rendered HTML upon interaction.
Conceptual Comparison:
If the old way was using jQuery's $.get( url , #outlet ), HTMX is the declarative evolution of that pattern.
<!-- Conceptual HTMX example: Updating a thread list without a full reload -->
<div hx-get="/threads/category/1" hx-target="#thread-list">
Click to Load Category 1
</div>
<div id="thread-list">
<!-- Server returns ONLY the HTML fragment for the list here -->
</div>
🗺 The Migration Strategy
Architecture Shift
The goal is to move from a complex JS-heavy flow to a streamlined server-centric flow:
Implementation Roadmap
The transition will be incremental rather than a "big bang" rewrite.
- Prerequisites: Finalize plugins, permissions, and the new parser.
- Phase 1: Migrate the Navbar to HTMX.
- Phase 2: Rewrite the Threads List.
- Phase 3: Convert the Thread Page.
- Phase 4: Update User Profiles.
- Bonus: Upgrade to the latest version of Bootstrap.
Note on the Admin Panel: The admin panel will not move to an SPA. The current system of reusable Django views and basic templates is highly efficient for adding new pages.
📊 Performance Metrics & Warnings
Initial JS Payload (Misago 0.39)
The following table outlines the weight of the JavaScript dependencies before the removal of React:
| File | Size (Uncompressed) | Size (Gzipped) |
|---|---|---|
vendor.js | 679kb | 214kb |
misago.js | 615kb | 124kb |
django-i18n.js | 102kb | 25.4kb |
hljs.js (Lazy) | 144kb | 49kb |
zxcvbn.js (Lazy) | 820kb | 430kb |
⚠️ The Transition Period
Users should expect a period where the site behaves as a Multi-Page Application (MPA).
"This means clicking some links or submitting forms (e.g., in user options) will trigger a full page reload. I will implement placeholder AJAX or HTMX in areas where a full reload would be unbearable."
✅ Progress Updates
June 12, 2024
The Forum Options page was replaced by Account Settings. This page is now powered by Django views and HTMX.
- Impact:
misago.jsdecreased by (uncompressed) / (gzipped).
July 25, 2024
The Threads Lists were rewritten from scratch using Django views and HTMX.
- Impact:
misago.jsdecreased by (uncompressed) / (gzipped).