"Commands are stateless functions. When they need to remember something together, you give the app a memory: managed state."
Register Once, Inject Everywhere
A command by itself forgets everything between calls. To share data — a config, a database pool, a counter, a cache — you manage it on the Builder with .manage(value). After that, any command can ask for it by declaring a parameter of type tauri::State<T>. Tauri sees that parameter and injects the managed instance automatically. The frontend never passes it; it lives entirely in the core.
One Managed Value Per Type
Managed state is keyed by type. You manage one AppConfig, one Database, one Counter — asking for State<AppConfig> always gives you the same instance. If you need two things of the same underlying type, wrap them in distinct newtypes (e.g. struct ReadPool(Pool) and struct WritePool(Pool)) so the type system can tell them apart. This is a feature: it makes 'which state?' unambiguous.
It's a Shared Reference
What you receive is a shared, read-only handle to the managed value. That's perfect for things you only read (a loaded config). But it means you cannot mutate fields directly through it — the borrow checker won't allow shared mutation. When state needs to change, you reach for interior mutability (a Mutex), which is exactly the next lesson. For now: register read-mostly state and inject it into the commands that need it.