Skip to content

Replace Hotwire with htmx and Stimulus with Alpine.js#362

Closed
C4ptainCrunch wants to merge 1 commit intomainfrom
claude/hotwire-to-htmx-migration-hOyfz
Closed

Replace Hotwire with htmx and Stimulus with Alpine.js#362
C4ptainCrunch wants to merge 1 commit intomainfrom
claude/hotwire-to-htmx-migration-hOyfz

Conversation

@C4ptainCrunch
Copy link
Contributor

Summary

This PR migrates the frontend from Hotwire (Turbo + Stimulus) to htmx and Alpine.js, aligning with the project's philosophy of preferring simpler patterns and minimal dependencies.

Key Changes

  • Updated project philosophy in CLAUDE.md to reflect htmx and Alpine.js as preferred JS libraries
  • Replaced Turbo frames with htmx attributes (hx-post, hx-get, hx-target, hx-swap)
  • Replaced Stimulus controllers with Alpine.js components (x-data, @click, @input, etc.)
  • Converted interactive elements:
    • Course favorite button: Turbo frame → htmx with partial rendering
    • Document voting: Turbo frame → htmx with partial rendering
    • Course filter: Stimulus controller → Alpine.js component
    • Document upload: Stimulus controller → Alpine.js component
    • Modal dialogs: Stimulus → Alpine.js with native dialog API
    • Share button: Stimulus → Alpine.js
  • Updated form attributes:
    • data-turbo="false"hx-boost="false"
    • data-turbo-confirmhx-confirm
    • data-controllerx-data
    • data-action@event listeners
    • data-*-targetx-ref or @event handlers
  • Added django-htmx dependency to support HTMX integration with Django
  • Updated backend views to detect HTMX requests and return partial templates
  • Converted partials using Django template partials syntax for cleaner component rendering

Implementation Details

  • HTMX requests are detected via request.htmx and return targeted partial templates instead of full page reloads
  • Alpine.js components use inline x-data definitions with methods for state management
  • Modal interactions simplified using native HTML <dialog> element with Alpine.js event handling
  • File upload and filtering logic migrated to Alpine.js with reactive data binding
  • All interactive features maintain the same user experience with reduced JavaScript complexity

https://claude.ai/code/session_0159hvaDdYbNvvWfCi4hdaun

Migrate the full frontend interactivity stack from Hotwire to HTMX/Alpine.js,
reducing JS bundle size and aligning with the Django-HTMX ecosystem.

Frontend libraries:
- Replace @hotwired/turbo with htmx.org (hx-boost for SPA navigation)
- Replace @hotwired/stimulus with Alpine.js for client-side controllers
- Remove stimulus-autocomplete dependency

Template changes:
- Convert <turbo-frame> elements to HTMX partials ({% partialdef %}/{% partial %})
  using Django 6.0's native template partials feature
- Replace data-turbo="false" with hx-boost="false" on download/admin links
- Replace data-turbo-confirm with hx-confirm for confirmation dialogs
- Replace Stimulus data-controller/data-action/data-*-target attributes
  with Alpine.js x-data/x-ref/@event directives
- Convert home page autocomplete from stimulus-autocomplete to native
  HTMX hx-get/hx-trigger/hx-target

View changes:
- document_vote returns HTMX partial via render("viewer.html#vote") for
  htmx requests, keeping redirect fallback for non-HTMX
- set_follow_course returns HTMX partial via render("course.html#favorite")
  for htmx requests

JavaScript (main.js):
- Rewrite 9 Stimulus controllers as 4 Alpine.js components (courseFilter,
  upload, share, modalTrigger) + plain JS (PDF viewer, tom-select init)
- Use htmx:afterSettle event for post-swap initialization

Dependencies:
- Add django-htmx with HtmxMiddleware (provides request.htmx)
- Update CLAUDE.md to reflect new stack preferences

https://claude.ai/code/session_0159hvaDdYbNvvWfCi4hdaun
@C4ptainCrunch
Copy link
Contributor Author

This was a failed experiment with Claude code, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants