App state: data apps that remember
Every data app on Rig now has a place to keep small things: a review flag, an annotation, a saved view. Whatever you ask for in your AI tools or the Rig chat, the app remembers.
The problem it solves
A data app is a dashboard or app your team vibe-codes on company data, hosted and governed by Rig. Until now, those apps had nowhere to put anything of their own. Marking a row as reviewed, saving an annotation, keeping a filter between visits: each of those meant registering a typed table through the VDM write-back rail, with columns and SQL types declared up front.
That ceremony is right for a real table and pure overhead for a flag. So small state tended to go unsaved, and apps that should have remembered things reset on every visit. App state closes the gap with a schema-less store.
How app state works
Every data app gets its own key value store. A value is any piece of JSON, saved under a key the app picks. Values are versioned, so two people editing at once cannot silently overwrite each other, and every value records who last wrote it, and when.
State comes in two scopes. Shared is the default: one value every viewer of the app sees, so when one person marks a row reviewed, it is reviewed for everyone. User state is private to each person, the right home for saved views and personal settings.
The Inspector's new State tab lists every key an app has saved, in both scopes, with its version and author. You can filter across keys and values, edit any value as JSON, or delete it.
You don't have to engineer it
There is nothing to install and nothing to wire up. When you build or change a data app in Claude or Rig Chat, describe the behaviour you want: let me mark each order as reviewed, remember the filters I had open, keep a note on every account. The model picks the right storage on its own, because the rule for choosing is part of the context every Rig agent carries: app state when an app is remembering its own small things, a VDM write-back when the app should own a real, queryable table.
The plumbing is equally hands-off. The client SDK is injected into every dashboard Rig renders, keys need no registering, and the first write creates the store. Say what the app should do, not which rail to use. You never have to name the feature to get it.
App state or a VDM?
Both are write-back rails, and neither needs a deploy. The difference is a declaration versus nothing. A VDM write-back gives the app a typed table your whole team can query, and charges for it up front: you name the columns and their SQL types when you register it. App state asks for nothing up front, and in exchange it is not a table: values come back by key, not by SQL.
| App state | VDM write-back | |
|---|---|---|
| Setup | None. The store exists the moment an app first writes to it. | Declare the columns and their SQL types up front, in one registration call. |
| Shape | JSON values under keys the app chooses. | Typed rows in a real table. |
| Reading it back | By key or key prefix, from the app, an agent, or the Inspector. | Query it like any other table: SQL, dashboards, chat. |
| Who can write | Any viewer for their own private state; shared state takes an editor. | Editors and up, always. |
| Best for | Flags, annotations, saved views, app settings. | Scorecards, roll-ups, enriched tables your team queries. |
The rule of thumb: if the app is saving its own state, use app state. If the app owns data other people will query, give it a VDM. And because the choice is made by the model when you describe the feature, the rule of thumb is mostly for reading along, not for deciding.
For technical audiences and workspace editors
For technical audiences and workspace editors
Every dashboard Rig renders runs in an opaque-origin sandboxed iframe that never holds a session token or an API endpoint. SDK calls travel over a postMessage relay to the host page, which attaches auth and injects the app's id itself; an app id supplied by the iframe is discarded. That is what makes the namespace trustworthy: no app can reach into another app's state.
Storage is one derived.app_state table, JSONB values keyed by app, scope, user and key, behind the same per-tenant boundary as the VDM rail. Reads are open to any viewer of the app; writing shared state takes the editor role, writing your own private state does not. Agents reach the same store over MCP