JavaScript runtime
Brew’s client runtime is an ESM/IIFE bundle built on Alpine.js. The default script tag loads Alpine + Brew plugins and calls Brew.start() on DOMContentLoaded.
Globals
Section titled “Globals”After the script loads:
window.Brewwindow.AlpineLifecycle events on document:
| Event | When |
|---|---|
brew:init / brew:initializing |
Before Alpine plugins and root selectors are wired — register hooks/directives here |
brew:initialized |
After Alpine.start() and components are live |
Finding components
Section titled “Finding components”Brew.find(id)Brew.first()Brew.getByName('counter')Brew.all()Brew.navigate('/posts')Brew.dispatch('saved', { id: 1 })Brew.dispatchTo('counter', 'bump', {})Brew.on('saved', handler)Every component root exposes $wire through Alpine (magic name wire):
| API | Role |
|---|---|
$wire.prop |
Read / assign ephemeral state |
$wire.$get(path) |
Deep read |
$wire.$set(path, value, live?) |
Deep set; live triggers a round-trip |
$wire.$toggle(prop) |
Flip boolean |
$wire.$call(method, …args) |
Invoke action |
$wire.method(…args) |
Same as $call |
$wire.$refresh() |
Re-render |
$wire.$commit() |
Flush pending updates |
$wire.$el / $wire.$id |
Root element / id |
$wire.$watch(path, fn) |
Watch state |
$wire.$hook(name, fn) |
Component-scoped hook |
$wire.$errors |
Validation bag (has / first / get / all / clear) |
$wire.$refs / $wire.$refs(name) |
Elements marked wire:ref |
$wire.$dirty(path?) |
Whether ephemeral state diverges from the last server snapshot |
$wire.$on / $wire.$dispatch* |
Event bridge (see Events) |
$wire.$entangle(name, live?) |
Alpine ↔ Brew two-way binding |
$wire.$intercept / $interceptAction / $interceptMessage / $interceptRequest |
Per-component request interceptors |
$wire.$js |
Access queued JS evaluation helpers |
$wire.$island(name) |
Target an island re-render (when using islands) |
document.addEventListener('brew:init', () => { Brew.hook('commit', ({ component, respond }) => { /* … */ }) Brew.hook('request', ({ respond }) => { /* … */ }) Brew.hook('morph', ({ el, component }) => { /* … */ }) Brew.hook('morph.updating', ({ el, toEl, component }) => {}) Brew.hook('component.init', ({ component, cleanup }) => {}) Brew.hook('element.init', ({ el, component }) => {}) Brew.hook('effect', ({ component, effects }) => {})})Morph sub-hooks: morph.updated, morph.removing, morph.removed, morph.adding, morph.added.
Interceptors
Section titled “Interceptors”Prefer interceptors for request lifecycle control:
Brew.interceptAction(({ action, onCancel }) => { /* … */ })Brew.interceptMessage(({ message, cancel, onSuccess }) => { /* … */ })Brew.interceptRequest(({ request, onError, onFailure }) => { /* … */ })Legacy request / commit hooks remain for older integrations.
Custom directives
Section titled “Custom directives”Brew.directive('tooltip', ({ el, directive, component, cleanup }) => { // wire:tooltip="…"})Built-in directives
Section titled “Built-in directives”| Group | Directives |
|---|---|
| Binding | wire:model (+ modifiers), wire:show, wire:text, wire:bind:* |
| Actions | wire:click, wire:submit, any wire:<event>, wire:init, wire:confirm |
| UX | wire:loading, wire:dirty, wire:offline, wire:cloak, wire:poll, wire:intersect, wire:sort |
| Morph | wire:key, wire:ignore, wire:replace, wire:transition, wire:stream, wire:ref |
| Navigate | wire:navigate, wire:current, wire:scroll |
| Islands | wire:island (+ .append / .prepend) |
Morph behaviour
Section titled “Morph behaviour”- Keyed by
wire:keyandwire:id - Respects
wire:ignore/wire:ignore.self/wire:ignore.children wire:replace/wire:replace.selfswaps instead of morphingwire:transition+effects.transitionparticipate in the View Transitions API when available- Block markers from Crema keep loops/conditionals stable
Errors
Section titled “Errors”| Response | Client behaviour |
|---|---|
| 419 (expired / checksum) | Page-expired prompt to refresh |
500 (when app.debug) |
Debug modal with details |
| Custom | onError / request interceptors can short-circuit |
Manual ESM
Section titled “Manual ESM”If you bundle Brew yourself, set window.brewScriptConfig (or emit @brewScriptConfig) and call Brew.start() after your Alpine setup. The default auto-start is skipped when script config is present.
import { Brew, Alpine } from '@konaframework/brew'// optional: Alpine.plugin(yourPlugin)Brew.start()Bundled Alpine plugins at start: morph, intersect, sort, resize, collapse, anchor, focus, persist, mask.
- Alpine.js coupling — coexistence rules
- Actions — server methods
$wirecalls - Events — dispatch and listeners
- Forms —
wire:modelmodifiers