Skip to content
Brew

Brew properties

Properties are the public state Brew dehydrates into the snapshot and rehydrates on every update. Only members declared on your subclass count—base Component members are never state.

class Profile : Component() {
var name = ""
var age = 0
var tags = mutableListOf<String>()
}

Prefer var with a backing field. Private / protected members are invisible to the browser.

Scalars, lists/maps/sets, enums, java.time types, BigDecimal / BigInteger, UUID, data classes / DTOs, and objects implementing Wireable (toBrew / fromBrew). Nested paths such as todos.0.title work through synthesizers.

Wrong types from the client raise a property-type mismatch (request rejected). Locked or unknown properties are refused.

Method Behaviour
fill(map) Assign known keys; ignore unknown
reset() / reset("a", "b") Restore initial values (fresh instance)
resetExcept("keep") Reset everything else
pull("title") Return value and reset
pull("a", "b") Return map and reset those keys
only("a", "b") Snapshot subset
all() Full public state map
fun clearForm() {
reset("name", "email")
}
fun importDraft(data: Map<String, Any?>) {
fill(data)
}

Mark fields the browser must not write:

@Locked
var userId = 0
@Locked
public int userId = 0;

Client updates to a locked property throw CannotUpdateLockedPropertyException.

Memoized derived values from a zero-arg public method:

@Computed
fun remaining(): Int = items.count { !it.done }

Templates read them as normal data ({{ remaining }}). Options:

Parameter Role
persist Cache across requests for this instance
cache Cache across all instances of the class
seconds TTL (default 3600)
key Explicit cache key when cache is true
tags Informational tags for tag-aware stores

Forget a memoized value:

forgetComputed("remaining")

Or read explicitly: computed<Int>("remaining").

$wire.count // read
$wire.count = 5 // queue an update
$wire.$set('count', 5, true) // set + live round-trip
$wire.$get('todos.0.title')
$wire.$toggle('open')
  • Only public subclass properties are state.
  • Only public subclass methods (not render / lifecycle / mount) are callable actions.
  • Snapshots are checksummed with app.key; tampering fails verification.
  • Hydration uses an allow-list security policy for synthesizable classes.
  • Actions — methods and $wire
  • Lifecycle — updatedFoo hooks when properties change
  • Forms — bind inputs with wire:model