Architecture Frontend Stack

Frontend Stack

IOTA SDK uses server-rendered HTML with progressive enhancement for server-owned pages and SolidJS for routes with substantial client-owned interaction state. See the Solid client runtime for the ownership and persistence boundaries.

Stack Overview

graph TB
    subgraph "Frontend Stack"
        A[Templ] -->|Generates| B[HTML]
        C[HTMX] -->|Enhances| B
        D[Alpine.js] -->|Interactivity| B
        E[Tailwind CSS] -->|Styles| B
    end
    
    subgraph "Backend"
        F[Go Controllers]
        G[Templates]
    end
    
    F -->|Data| G
    G -->|Renders| A

Technology Choices

TechnologyPurposeWhy
TemplHTML templatingType-safe, Go-native
HTMXAJAX via HTMLMinimal JS, progressive enhancement
Alpine.jsReactivityLightweight, declarative
Tailwind CSSStylingUtility-first, rapid development
SolidJSClient routesDirect reactive state for complex interaction

Request/Response Flow

Standard Page Load

sequenceDiagram
    participant Browser
    participant Controller
    participant Service
    participant Templ
    
    Browser->>Controller: GET /page
    Controller->>Service: Fetch data
    Service-->>Controller: Return models
    Controller->>Templ: Render template
    Templ-->>Controller: HTML string
    Controller-->>Browser: Full HTML page

HTMX Request

sequenceDiagram
    participant Browser
    participant HTMX
    participant Controller
    participant Templ
    
    Browser->>HTMX: User action (hx-post, etc.)
    HTMX->>Controller: AJAX request + HX headers
    Controller->>Controller: Check htmx.IsHxRequest(r)
    Controller->>Templ: Render partial template
    Templ-->>Controller: HTML fragment
    Controller-->>HTMX: HTML + HX-Trigger headers
    HTMX->>Browser: Swap DOM content

Templ

Type-Safe Templates

Templ provides compile-time type safety for HTML templates:

Benefits:

  • Catch errors at compile time, not runtime
  • IDE support and autocomplete
  • No template parsing overhead
  • Type-safe data passing

Template Structure

graph TD
    A[Page Template] --> B[Layout Template]
    A --> C[Component 1]
    A --> D[Component 2]
    
    B --> E[Header]
    B --> F[Navigation]
    B --> G[Footer]

Template Types

TypeExtensionPurpose
Pages*.templFull page templates
Components*.templReusable UI components
Layouts*.templPage wrappers
Partials*.templHTMX fragments

HTMX

Progressive Enhancement

HTMX adds AJAX functionality via HTML attributes:

graph LR
    A[Plain HTML Form] -->|hx-post| B[AJAX Submission]
    B -->|hx-target| C[Partial Update]
    C -->|hx-trigger| D[Client Event]

Key Attributes

AttributePurposeExample
hx-getAJAX GET requestLoad content dynamically
hx-postAJAX POST requestSubmit forms
hx-targetUpdate target elementSwap specific DOM
hx-swapSwap methodinnerHTML, outerHTML, beforeend
hx-triggerEvent triggerclick, change, load
hx-confirmConfirm dialogUser confirmation

Server-Side Handling

graph TD
    A[Request] --> B{Is HxRequest?}
    B -->|Yes| C[Render Partial]
    B -->|No| D[Render Full Page]
    C --> E[Return HTML Fragment]
    D --> F[Return Full HTML]

Alpine.js

Lightweight Reactivity

Alpine.js adds JavaScript interactivity declaratively:

Use Cases:

  • Dropdown menus
  • Modal dialogs
  • Form validation feedback
  • Toggle switches
  • Tabs

Integration with HTMX

sequenceDiagram
    participant Alpine
    participant HTMX
    participant Server
    
    Alpine->>Alpine: User interaction
    Alpine->>HTMX: Trigger htmx-request
    HTMX->>Server: AJAX call
    Server-->>HTMX: Response
    HTMX->>Alpine: DOM updated
    Alpine->>Alpine: Reinitialize components

Tailwind CSS

Utility-First Styling

Compose designs from utility classes:

graph LR
    A[Component] --> B[Container]
    B --> C[Typography]
    B --> D[Spacing]
    B --> E[Colors]
    B --> F[Layout]

Configuration

Tailwind is configured at the repository root (tailwind.config.js) and per-applet (e.g. modules/bichat/presentation/web/tailwind.config.js). There is no web/src/css/ path.

  • Custom colors for branding
  • Extended spacing scale
  • Plugin configurations

Component Architecture

Server Components

Pure server-rendered components:

graph TD
    A[Controller] -->|Data| B[Templ Component]
    B -->|Renders| C[HTML]
    C -->|Sent| D[Browser]

Interactive Components

Components with Alpine.js interactivity:

graph TD
    A[Controller] -->|Initial HTML| B[Templ Component]
    B -->|Includes| C[Alpine Directives]
    C -->|Hydrates| D[Interactive Component]

State Management

Server State

Primary state lives on the server:

graph LR
    A[Browser] -->|HTTP| B[Controller]
    B -->|Query| C[Service]
    C -->|Fetch| D[(Database)]
    D -->|State| C
    C -->|Data| B
    B -->|HTML| A

Client State

Minimal state in Alpine.js:

  • UI state (open/closed, selected tab)
  • Form draft state
  • Temporary user preferences

Best Practices

Progressive Enhancement

  1. Start with HTML - Works without JavaScript
  2. Add HTMX - Enhance with AJAX
  3. Add Alpine.js - Add interactivity where needed

Performance

  1. Minimize JS - Server-render when possible
  2. Partial Updates - HTMX for targeted updates
  3. Lazy Loading - Load components on demand
  4. Bundle Size - Alpine.js is ~15kb, minimal overhead

Comparison with SPA Frameworks

AspectIOTA SDKReact/Vue SPA
Initial LoadFast (HTML)Slower (JS bundle)
InteractivityProgressiveFull client-side
SEONativeRequires SSR
ComplexityLowerHigher
StateServer-firstClient-first

Next Steps

Last updated on