An app surface is the part your user sees. It should read named data, render every state, and send named requests. It should not import package storage details.
A founder adds aCustomers screen. The screen needs a list, a loading state, an empty state, and one action: archive a customer.Read
The surface asks for a stable input name and renders loading, error, empty, and success states.
→
Render
The user sees concrete product data: customers, messages, tasks, rooms, invoices, or whatever your product owns.
→
Act
The surface sends a small request to a target instead of mutating local files by hand.
Surface contract
| Piece | Surface owns | Surface does not own |
|---|---|---|
| Reads | Which data name it needs and how to render each state | Storage layout or package admission |
| Actions | Button intent, payload shape, pending/error/success UI | Target execution details |
| Layout | Local component structure inside the surface | Global navigation and device/account placement |
| Copy | User-facing words for the product moment | Private setup details |
Minimal shape
What not to do
Common failures
| Symptom | Cause | Fix |
|---|---|---|
| The component crashes before data arrives | It renders only the success path | Add loading, error, empty, and success states |
| The screen imports or parses package file names | The surface is bypassing named data reads | Read through useBitfieldData(...) |
| Every button sends a vague command | The action reply shape is not product-shaped | Use a named target like customers.archive |
| The UI cannot show success or failure | The request result is ignored | Render pending, success, and failure feedback |
Verify
| Check | Passes when |
|---|---|
| Loading path | The screen shows a visible loading state before data arrives |
| Error path | The screen shows a visible error state when the read fails |
| Empty path | The screen explains what the user sees when no records exist |
| Success path | The screen renders product data, not storage vocabulary |
| Request path | The button calls a named target with a small payload |