Skip to main content

The problem

Component props are build-time values. A parent counter and a child header that both edit the same number need either duplicated state, callback props, or an external store.

What this looks like without Aero

Parents pass initial values; children copy them into local variables. Keeping parent and child in sync means custom events or shared global state.

How Aero helps

Reactive props let a parent pass a state binding into a child with bind:<name>. The child declares the prop in <script is:state> and marks it mutable with Aero.bindable(). Reactive props are readonly by default. Only props declared with Aero.bindable() (or Aero.bindable(fallback)) accept writes from the child.

Parent: pass a binding

Child: accept a bindable reactive prop

Aero.bindable() marks count as writable from the child. Parents must pass bindable props with bind:count — one-way count="{ count }" is an error. Aero.bindable(0) makes the prop optional when the parent omits bind:count.

Required vs optional

Destructuring defaults drive the contract: Required bindable props must be passed with bind:<name>. aero check and the VS Code extension report missing or one-way bindings.

Readonly reactive props

Props destructured from Aero.props without bindable() are readonly in the child state script. Assigning to them is a compile-time diagnostic:
Pass readonly reactive props with label="{ label }". To allow the child to mutate a prop, use Aero.bindable() on the child and bind:<name> on the parent.

Build-time props vs reactive props

Build scripts still use Aero.props for static attributes. State scripts use Aero.props with bindable() for reactive data.