Skip to main content
Feather builds UIs in three layers. Each solves a different problem, and keeping the boundaries between them clear is what stops an app getting complicated as it grows.

Components

Server-rendered Jinja2 macros, comparable to Rails view components or Laravel Blade components. Reusable pieces of UI that render to HTML on the server. No JavaScript, no hydration.

HTMX

Server interactions without page reloads, the same idea as Hotwire in Rails or Livewire in Laravel. Click a button, the server returns HTML, HTMX swaps it into the page.

Islands

Small JavaScript components for UI that needs state on the client. The name comes from Astro’s islands architecture.

Choosing a layer

Start with components for anything static. Reach for HTMX when you need server data without a page reload. Use islands only when state has to live on the client. Most features need nothing past the first two.
Buttons, cards, modals, form inputs. Anything reusable that renders to HTML. You call them like {{ button("Save", variant="primary") }}.
Forms, search, pagination, like buttons. HTMX covers most of what you would otherwise write with React and fetch, without the JavaScript. Server-side rendering with targeted DOM updates.
Drag-and-drop, audio players, live updates. Anywhere a round trip to the server would feel slow. Close to writing a small React component, without React’s runtime.
Dark mode is wired into every scaffolded app and every framework component. See Dark mode for the dark: conventions your own CSS should follow.