State Management with $store
Share state across components using Alpine.store().
Global State in Alpine
Alpine provides a simple but powerful state management solution using Alpine.store() and the $store magic. It's fully reactive – any component that accesses a store property will automatically re‑render when that property changes.
Why Not a Library?
For many applications, a dedicated state management library like Redux or Vuex is overkill. Alpine's stores give you global reactivity without extra dependencies, and they integrate perfectly with the rest of Alpine's ecosystem.
Example: Shopping Cart Store
Alpine.store('cart', {
items: [],
add(product) { this.items.push(product) },
remove(id) { this.items = this.items.filter(i => i.id !== id) },
get total() { return this.items.length },
get totalPrice() { return this.items.reduce((sum, i) => sum + i.price, 0) }
})Using in Multiple Components
Any component on the page can read and write to the cart store. All UI will stay in sync.
<!-- Product list -->
<button @click="$store.cart.add({ id: 1, name: 'Apple', price: 0.99 })">Add to cart</button>
<!-- Cart badge -->
<span x-text="$store.cart.total"></span>
<!-- Cart summary -->
<ul>
<template x-for="item in $store.cart.items" :key="item.id">
<li x-text="item.name"></li>
</template>
</ul>Accessing Stores in JavaScript
You can also interact with stores from outside Alpine components. This is useful for initialising state from server‑side data or for testing.
const cart = Alpine.store('cart')
cart.add({ id: 2, name: 'Banana', price: 0.79 })💡 Tip
Store methods can be async, and you can use $watch inside a component to react to store changes.
Can I use multiple stores?
Yes, you can create as many stores as you need. Each store is a separate namespace.