You don't need React for a dropdown menu. You don't need Vue for a tab component. You need Alpine.js.
What Is Alpine.js?
Alpine.js is a lightweight JavaScript framework for composing behavior directly in HTML. Think of it as Tailwind for JavaScript.
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ open: false }">
<button @click="open = !open">Toggle</button>
<div x-show="open" x-transition>
Hello! I'm a dropdown.
</div>
</div>
That's a complete interactive component. No npm. No build. No bundler.
Core Directives
<!-- Reactive data -->
<div x-data="{ count: 0 }">
<span x-text="count"></span>
<button @click="count++">+</button>
</div>
<!-- Conditional rendering -->
<div x-data="{ show: false }">
<div x-show="show" x-transition>Visible when show=true</div>
<template x-if="show"><p>Rendered conditionally</p></template>
</div>
<!-- Loops -->
<div x-data="{ items: ['Apple', 'Banana', 'Cherry'] }">
<template x-for="item in items" :key="item">
<li x-text="item"></li>
</template>
</div>
<!-- Two-way binding -->
<div x-data="{ search: '' }">
<input x-model="search" placeholder="Search...">
<p>You typed: <span x-text="search"></span></p>
</div>
Real Example: Tabs Component
<div x-data="{ tab: 'home' }">
<nav>
<button @click="tab = 'home'" :class="{ 'active': tab === 'home' }">Home</button>
<button @click="tab = 'about'" :class="{ 'active': tab === 'about' }">About</button>
<button @click="tab = 'contact'" :class="{ 'active': tab === 'contact' }">Contact</button>
</nav>
<div x-show="tab === 'home'">Home content</div>
<div x-show="tab === 'about'">About content</div>
<div x-show="tab === 'contact'">Contact content</div>
</div>
In React, this would be a component file, useState, onClick handlers, conditional rendering, CSS modules. In Alpine: one HTML block.
Fetching Data
<div x-data="{ users: [] }" x-init="users = await (await fetch('/api/users')).json()">
<template x-for="user in users" :key="user.id">
<div x-text="user.name"></div>
</template>
</div>
Why Alpine.js
- 7KB gzipped (React + ReactDOM = 172KB)
- Zero build step — CDN script tag and go
- Perfect with server-rendered HTML — Django, Rails, Laravel, Go templates
- Tailwind CSS companion — same philosophy: utility-first, in your HTML
- Learn in 15 minutes — 15 directives, 6 properties, 2 methods. That's the whole API.
Building web tools or need data solutions? Check out my developer toolkit or email spinov001@gmail.com.
Top comments (0)