The problem
Componentprops 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 withbind:<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 fromAero.props without bindable() are readonly in the child state script. Assigning to them is a compile-time diagnostic:
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.