⚡
🎛️
📦
If you're building a static site with Astro and you need a dropdown menu, a mobile hamburger toggle, or a theme switcher, do not reach for React. You don't need a 40KB JavaScript framework for a
display: none and some event listeners. Alpine.js exists for exactly this reason — reactive HTML attributes that cost almost nothing.
Alpine is a 16KB JavaScript library that brings reactivity to your HTML with declarative directives: x-data for state, x-show for conditional rendering, @click for event handling. No JSX, no build step required, no component hydration overhead. Write it directly in your .astro templates or load it via CDN. The browser parses your HTML, Alpine initializes, and interactions work instantly.
Here's the pattern at Velocity X. The header dropdown is pure Alpine:
{``}
That's it. No React component, no client island, no JavaScript build output. Alpine reads x-data, creates reactive state, wires up the click handler, and hides/shows the dropdown based on open. When you click outside, @click.outside closes it. The Astro page stays static. Only Alpine's 16KB loads at runtime.
Compare that to the React island approach: you'd create a Dropdown.tsx component, import it into your Astro template with client:lazy, Astro would bundle React + your component, and the browser would hydrate that island on page load. That's another 40KB of framework code for a toggle.
The mobile menu works the same way. Set up x-data="{ mobileOpen: false }", toggle on hamburger click, and use x-show to hide/show the nav on mobile. No state management library, no context providers, no hooks. Just HTML + Alpine directives.
Theme toggling is the clearest example. Alpine's $store gives you shared state across the page:
{`
`}
Alpine watches the store, updates the class binding, and the CSS cascade handles dark mode. One 16KB script, reactive everywhere, no JavaScript written.
The catch: Alpine is reactive but not composable. You can't build complex component hierarchies or share elaborate logic across many interactive islands. If you're building a form with nested validation, conditional fields, and error states, Alpine gets awkward. That's where you reach for React or Vue. But for the 80% of static sites that just need some dropdowns and toggles, Alpine is the right tool.
We use it in production across all Velocity X sites. It's reliable, tiny, and fast. Astro handles the static architecture, Alpine adds the interactivity, and users get a fully functional site with under 100KB of JavaScript total. No over-engineering, no picking a SPA framework for a dropdown.
Pick the smallest tool that solves the problem. For trivial interactivity on static sites, that tool is Alpine.
For deeper architectural guidance on when to use static, server, or client rendering, check our AI-Ready Website Architecture post. Ready to ship? See Velocity X pricing.