On this pageOverview
Model
The Model represents your entire application state in a single, immutable data structure defined with Effect Schema. Everything your app can be at any moment lives here — not scattered across components, not split between local and global state.
In the restaurant analogy, the Model is the waiter’s notebook — the running picture of everything happening right now. Orders in flight, tables seated, who’s waiting for dessert. Every fact about the current state of the restaurant lives in one place.
In the counter example, the Model is a Struct with a single field:
import { Schema as S } from 'effect'
// MODEL
const Model = S.Struct({
count: S.Number,
})
type Model = typeof Model.TypeTypeScript types disappear when your code compiles — they help the compiler check your code, but they don’t exist at runtime. Schema keeps that type information alive as a value. This gives Foldkit knowledge of your Model at runtime: it can compare models for equality, decode state from unknown sources, and manage resource lifecycles — things that require knowing the shape of your data, not just its type. You’ll see these capabilities pay off as the counter grows, especially on the Subscriptions page.
The counter starts with a single field, but models grow with your app. When we add auto-counting later, the Model will expand:
import { Schema as S } from 'effect'
// When the counter gains auto-counting,
// the Model grows to hold new state:
const Model = S.Struct({
count: S.Number,
isAutoCounting: S.Boolean,
})
type Model = typeof Model.TypeOne state tree, not many
Think of the Model as combining useState, useContext, and your Redux store into one typed structure. Instead of state scattered across components, everything lives here.
The Model captures what your app is at any moment. But how does it change? In Foldkit, every change starts with a Message — a fact about something that happened.