Writing a UX Spec
Published May 22, 2026 · Last updated May 22, 2026 · 3 min read
The UX spec is the second phase in a three-phase spec pipeline. It sits between the product spec — which defines outcomes — and the technical spec — which maps those outcomes to code. Its job is to make the experience concrete and reviewable before any implementation begins.
Why This Phase Exists
Product specs describe what success looks like. Technical specs describe how code achieves it. Neither captures the interaction itself — the sequence of clicks, the layout of information, the timing of feedback, the edge states a user might encounter. Without a UX spec, the agent invents an interface based on what is easiest to build, which is rarely what is best for the user.
The UX spec is also a communication artifact. Sharing a prototype with a colleague takes seconds and produces useful feedback. Sharing a product spec requires them to imagine the interface. Sharing a technical spec requires them to read code. The UX spec gives reviewers something they can actually react to before any code exists.
State Inventory as a Spec Tool
The most reliable way to write a UX spec is to enumerate every distinct state the user might encounter. For each state, capture what triggers it, what the UI shows, and whether it is a happy path, an edge case, or an error.
The notification panel example below shows what a complete state inventory looks like:
| State | Description | Category |
|---|---|---|
| Empty state | No notifications. Friendly message, no badge visible. | happy |
| Single notification | Badge shows "1". Panel shows comment with highlighted text. | happy |
| Many notifications | Badge shows "99+". Scrollable list, newest first. No pagination. | happy |
| Loading | Skeleton placeholders. Badge hidden until count is known. | edge |
| Deleted document | Source doc removed. Show dimmed item with "document deleted" label. | edge |
| Removed user | Commenter no longer in workspace. Show generic avatar + name. | edge |
| Error state | WebSocket failed. Show last-known state + "reconnecting" label. | error |
| Simultaneous notifications | Two comments arrive at once. Badge bumps to new total. No race. | edge |
A state inventory like this makes gaps visible before implementation. If a state is not in the table, the agent will not handle it.
Building in Obvious
In Obvious, you build the UX spec rather than describe it. Rather than writing prose and hoping the agent interprets it correctly, you create the actual components as artifacts the agent can open by ID during implementation.
Workbook sheets as state models. Define the data shape behind each UI state in a workbook sheet. A "Notifications" sheet with columns for type, source user, target document, timestamp, read status, and content gives the agent a concrete data contract — not an abstraction.
Prototype on the sandbox. Build the actual component in HTML/CSS on Obvious's sandbox and register it as an artifact. A rendered, interactive prototype eliminates ambiguity that words cannot. The agent can open it, inspect it, and match the behavior exactly.
Kanban or checklist views for state coverage. List every state the UI needs to handle. The agent uses this as its acceptance checklist during implementation, working through each state systematically.
Reference artifacts by ID. art_xyz is unambiguous. "The notification panel design" is a search problem. When you reference an artifact by ID in your spec, the agent opens it directly rather than searching for something that might match.
A well-structured UX spec project in Obvious might include a state model sheet (art_abc), a state checklist view (art_def), and a sandbox prototype (art_ghi) — each scoped tightly to the feature, each referenceable by ID from both the UX spec document and the downstream technical spec.