Components & State
The Vango Developer Guide is exhaustive, but the launch version reduces the state model to the decisions you make every day while building app code.
Local Reactive State
Use setup.Signal for local state owned by one component.
1count := setup.Signal(&s, 0)
2search := setup.Signal(&s, "")
Use setup.Memo for derived values that should recompute from other reactive inputs.
Allocate both signals and memos unconditionally inside vango.Setup. Do not allocate reactive primitives inside render.
Async Reads
1user := setup.ResourceKeyed(&s,
2 func() int { return props.Get().UserID },
3 func(ctx context.Context, id int) (*User, error) {
4 return repo.GetUser(ctx, id)
5 },
6)
Use Resources when:
data can load asynchronously
the request is a read
render should stay pure
Async Mutations
1saveProfile := setup.Action(&s,
2 func(ctx context.Context, in SaveProfileInput) (*Profile, error) {
3 return repo.SaveProfile(ctx, in)
4 },
5)
Use Actions when:
the change originates from live UI
the work may block
you want a structured pending/error/result surface
Persisted State Surfaces
vango.SessionKey[T] | Small session-owned durable values |
|---|---|
setup.SharedSignal | Session-shared persisted state |
setup.GlobalSignal | App-global persisted state |
Persist only deliberate UX state. Do not use persisted primitives as a default replacement for local reactive state.
SessionKey declarations should be package-scoped and typed:
1type ThemePrefs struct {
2 Mode string
3}
4
5func (ThemePrefs) VangoSchemaID() string {
6 return "myapp:ThemePrefs:v1"
7}
8
9var ThemeKey = vango.NewSessionKey[ThemePrefs](
10 "theme",
11 vango.Default(ThemePrefs{Mode: "system"}),
12)
Persisted initializers must be deterministic. Use literals, constants, and simple composite values; do not derive persisted initial values from props, time, environment, random IDs, I/O, or helper calls.
List Identity
Use RangeKeyed for dynamic collections:
1RangeKeyed(items.Get(),
2 func(item Todo) string { return item.ID },
3 func(item Todo) *vango.VNode {
4 return Li(Text(item.Text))
5 },
6)
The Short Checklist
Allocate all reactive primitives in Setup.
Never allocate reactive primitives in render.
Keep writes on the session loop.
Use keyed lists whenever order or membership can change.
Persist only what must survive navigation, reconnect, or deploy.
Add a stable VangoSchemaID() when a persisted type should survive renames or package moves.