NashTech Blog

BUILDING A MODERN WEB APP WITH HTMX + ALPINEJS

Table of Contents

1. Introduction

In today’s web development landscape, there’s a growing movement back to simplicity. While React, Vue, and Angular dominate the frontend ecosystem, they often introduce unnecessary complexity for many applications. Enter HTMX and Alpine.js – two lightweight libraries that bring modern interactivity to traditional server-rendered HTML.

In this post, I’ll walk you through how I built a complete booking application using these technologies, demonstrating that you can create rich, interactive web experiences without the overhead of heavy JavaScript frameworks.

2. Why htmx + AlpineJS?

The Problem with Modern SPAs

  • Bundle Size: React apps can easily reach 100KB+ just for the framework
  • Complexity: State management, routing, and build tools add layers of complexity
  • SEO Challenges: Client-side rendering can hurt search engine optimization
  • Development Overhead: Setting up build pipelines, managing dependencies, and debugging framework-specific issues

The HTMX + Alpine.js Solution

  • Lightweight: HTMX is ~14KB, Alpine.js is ~15KB (combined: ~29KB vs 100KB+)
  • Progressive Enhancement: Works without JavaScript, enhances with it
  • Server-First: Leverages your existing backend knowledge
  • No Build Step: Write HTML, CSS, and minimal JavaScript directly
  • Familiar: Uses standard web technologies you already know

3. Project overview: Booking application

I built a complete booking system with:

  • User authentication via Google OAuth
  • Service selection (Hotel Room, Meeting Room, Spa Treatment)
  • Real-time slot availability
  • Booking management (create, edit, cancel)
  • Responsive design with modern UI/UX
  • Avatar caching system

Tech Stack:

  • Backend: Python Flask
  • Frontend: HTMX + Alpine.js
  • Styling: Custom CSS with modern design patterns
  • Database: PostgreSQL with SQLAlchemy
  • Authentication: Google OAuth via Flask-Dance

4. HTMX: Server-Driven Interactivity

What is HTMX?

HTMX allows you to access modern browser features directly from HTML, without writing JavaScript. It extends HTML with attributes that enable AJAX, CSS transitions, WebSockets, and more.

Key HTMX Features Used

– Form Submissions Without Page Reloads

– Dynamic content loading

– Realtime update

5. HTMX Benefits in Our App

  • No JavaScript Required: Forms work even without JavaScript
  • Server-Side Rendering: All HTML is generated on the server
  • Progressive Enhancement: Basic functionality works, enhanced with HTMX
  • SEO Friendly: Search engines see complete HTML content

6. Alpine.js: Reactive Components

What is Alpine.js?

Alpine.js is a lightweight JavaScript framework that provides reactive and declarative behavior to your HTML. It’s like Vue.js but much smaller and designed to work with server-rendered HTML.

Key Alpine.js Features Used

–  Reactive State Management

–  Two-Way Data Binding

– Event handling

– Computed Properties

7. Alpine.js Benefits in Our App

  • Reactive UI: UI automatically updates when data changes
  • Component-Based: Organize code into logical components
  • Lightweight: Only 15KB minified and gzipped
  • No Build Step: Write directly in HTML

8. Modern UX/UI without frameworks

– I built a modern, responsive design using:

  • CSS Grid & Flexbox: For responsive layouts
  • CSS Custom Properties: For consistent theming
  • Modern Selectors: For clean, maintainable CSS
  • Glassmorphism Effects: For contemporary visual appeal

– Reponsive design

– Interactive Elements

  • Hover Effects: Smooth transitions and transforms
  • Loading States: Visual feedback during operations
  • Success Animations: Celebratory feedback for user actions
  • Accessibility: Proper ARIA labels and keyboard navigation

9. Realtime Interaction

– Dynamic Slot Availability

– Live Form Validation

– Instant UI Updates

  • Tab Switching: Instant navigation between sections
  • Form State: Real-time validation and feedback
  • Booking Status: Immediate updates after operations
  • Slot Selection: Visual feedback for available/selected times

10.  Backend Integration

– Flask + HTMX Synergy

– Partial Template Rendering

– Database Operations

  • User Authentication: Google OAuth integration
  • Data Persistence: PostgreSQL with SQLAlchemy ORM
  • Real-Time Queries: Dynamic slot availability
  • User Isolation: Secure booking management

11. When to Use HTMX + Alpine.js

– Perfect for:

  • Content-Heavy Apps: Blogs, documentation, dashboards
  • Form-Heavy Applications: CRUD operations, data entry
  • Internal Tools: Admin panels, business applications
  • Marketing Sites: Landing pages, portfolios
  • Prototypes: Quick MVPs and proof of concepts

– Consider Alternatives When:

  • Complex State Management: Multi-step workflows, complex forms
  • Real-Time Features: Chat applications, live collaboration
  • Mobile Apps: PWA with offline capabilities
  • Large Teams: Need for strict component architecture

12. Challenges I Faced

– State Management Complexity

The Challenge: Managing form state, user selections, and UI updates across multiple components without a centralized state management system.

What Happened: Initially, I tried to manage everything with Alpine.js reactive variables, but this led to complex data flow and synchronization issues between the booking form, slot selection, and user interface.

Impact: Form validation became unreliable, and users experienced inconsistent behavior when switching between tabs or updating selections.

– HTMX Request Handling

The Challenge: Properly handling different response types (HTML vs JSON) and managing error states when HTMX requests failed.

What Happened: We initially returned HTML for all HTMX requests, but this made error handling difficult and prevented proper API integration for non-HTMX clients.

Impact: Poor error handling led to confusing user experiences and made debugging more difficult.

– Real-Time Slot Updates

The Challenge: Implementing real-time slot availability updates without WebSockets or complex polling mechanisms.

What Happened: We needed to show available time slots dynamically based on date selection and existing bookings, but the initial implementation was inefficient and didn’t scale well.

Impact: Users saw outdated availability information, leading to booking conflicts and frustration.

13. Solutions I Implemented

– Centralized State Management with Alpine.js

The Solution: Created a single bookingApp() function that manages all application state and provides methods for state updates.

– Smart HTMX Response Handling

The Solution: Implemented conditional response handling based on request headers and created reusable error handling patterns.

– Efficient Slot Availability System

14. What I learned?

– The Power of Progressive Enhancement

 Building a solid foundation that works without JavaScript, then enhancing it with HTMX and Alpine.js, creates a more robust and accessible application. Our forms work perfectly without JavaScript, ensuring accessibility and reliability. When JavaScript is available, HTMX adds smooth interactions and Alpine.js provides reactive updates.

– Server-Side Rendering is Still Relevant

 Modern web development doesn’t have to mean client-side everything. Server-side rendering with HTMX provides the best of both worlds.  We generate all HTML on the server, ensuring SEO benefits and fast initial page loads. HTMX then enables dynamic updates without losing these advantages.

– State Management Doesn’t Need to Be Complex

For many applications, simple state management with Alpine.js is more than sufficient and easier to maintain than complex state management libraries. Our single bookingApp() function manages all state with clear, predictable methods. No need for Redux, Vuex, or similar complexity.

15. Demo

Login with google

Booking form should enable when all field have been filled

List booking can edit and delete

The time have booked will disable

16. Project link

Source URL: https://github.com/danghieu1407/bookingapp.git

Picture of Hieu Nguyen Dang

Hieu Nguyen Dang

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top