Prototyping
User flow diagram: map every screen state, not just pages
How to draw a user flow diagram where each node is a screen state (empty, loading, error, success) and each arrow names the action behind it.
A user flow diagram maps the path a user takes through your product to finish one task, from the entry point to the result. The version worth drawing uses screen states as nodes (empty, loading, error, success) rather than whole pages, and labels every arrow with the action or event that moves the user on. Drawn that way, the diagram shows the situations that usually get forgotten, before anyone writes code.
What most user flow diagrams leave out
The classic flow diagram is a row of pages joined by arrows: Sign in, Dashboard, Settings. It reads well in a meeting, and it hides most of the work. A single “Sign in” box stands for at least five situations: the empty form, the form with a validation error, the request in progress, a wrong password, and a locked account. Each of those needs a design, copy, and a way forward.
When the diagram only shows pages, those situations get decided later, by whoever writes the code, often under time pressure. That is how a product ends up with a blank screen when a list is empty, or an error message that says “Something went wrong” and offers no next step.
States, not pages: the unit that makes a flow complete
A screen state is one situation of one screen, with its own content and its own actions. A screen is the set of its states. Drawing states as nodes gives the diagram three useful properties:
- Every node can be designed. “Checkout” is too vague to draw; “Checkout, card declined” is a specific screen.
- Every arrow has a cause. An arrow from “Checkout, filled” to “Checkout, card declined” is caused by “Payment is refused”, which tells the developer which event to handle.
- Gaps become visible. A state with no arrow out of it is a dead end. A state with no arrow into it is unreachable, or you forgot its trigger.
Here is how a few screens break down:
| Screen | States to draw |
|---|---|
| Project list | empty (first use), loading, filled, filtered with no results, error loading |
| New project modal | empty, validation error, saving, name already taken |
| Project page | default, archived, no access |
If you want a starting list for your own screens, the UI states checklist goes through the states most screens need.
How to draw a user flow diagram, step by step
- Pick one task and one entry point. For example: “A returning user resets a forgotten password, starting from the sign-in screen.” One diagram per task keeps it readable.
- List the screens on the happy path. Write down the screens a user sees when everything works, in order.
- List the states of each screen. For each screen, ask what it looks like before data arrives, with no data, with too much data, when input is invalid, when the server fails, and after success.
- Draw the arrows and name each trigger. A trigger is a user action (“Tap Save”, “Submit invalid form”) or a system event (“Request fails”, “Link expires”). Write it on the arrow.
- Add the exits. Cancel, back, close, sign out. A user who cannot leave a flow cleanly will leave the app instead.
- Check for dead ends and orphans. Every state except the goal needs at least one arrow out. Every state except the entry needs at least one arrow in.
Naming conventions that keep the map readable
- State labels are short and lowercase: “empty”, “error”, “modal open”, “email sent”.
- Triggers start with a verb and name the object: “Tap Resend code”, not “Click here”.
- System events are written as facts: “Request fails”, “Session expires”.
- One arrow per trigger. If two different actions lead to the same state, draw two arrows.
A worked example: resetting a password
Written as a table, or as a list in a text file, a flow is easy to review and easy to diff. Here is the password reset task from the steps above:
from trigger to
Sign in · default Tap "Forgot password" Reset · empty
Reset · empty Submit without an email Reset · validation error
Reset · empty Submit a valid email Reset · sending
Reset · sending Request succeeds Reset · email sent
Reset · sending Request fails Reset · network error
Reset · network error Tap Try again Reset · sending
Reset · email sent Tap Resend email Reset · sending
Reset · email sent Open the link in the email New password · empty
Reset · email sent Open an expired link New password · link expired
New password · link expired Tap Send a new link Reset · empty
New password · empty Submit a weak password New password · too weak
New password · empty Submit a valid password Sign in · password changed
Twelve arrows, for a flow that a page diagram would draw with three boxes. Look at what the table forces you to decide: what the user sees while the request is in flight, how they recover from a failed request, what happens with an expired link, and what the sign-in screen says after a successful reset. Each of those is a question for design and product, not something to improvise in code.
Note the “Reset · email sent” state as well: it needs a resend action, because email arrives late or lands in spam. Flows that cross channels (email, SMS, a push notification) are where users get stuck most often, so the moment they leave your screen deserves its own node.
Let your coding agent draft it from the code
For an app that already exists, the fastest first draft comes from the code. A coding agent can read routes, components and request handlers, and list the states each screen can render. A prompt like this works in Claude Code or a similar agent:
Read the routes and components of the password reset feature. List every
screen, every state each one can render (empty, loading, error, success,
modal open...), and every user action or system event that moves from one
state to another. Output a table with three columns: from, trigger, to.
Do not change any code. Then list the states that have no way out.
Review the output against what you know of the product. The agent will find states you forgot, and it will miss states the code does not handle yet, which are often the ones you most need to design. Keep the table in your repository, next to the feature, so it changes with the code.
Turning the diagram into linked frames
A diagram tells you which states exist; it does not show what they look like. The next step is to draw each state as a screen and keep the arrows between them, so a reviewer can follow the path and judge each screen on its own.
This is the model agentappbuilder uses. On its canvas, a frame is one state of one screen, the states of a screen sit side by side, and a flow link joins two frames with its trigger, drawn as an arrow labelled “Tap Save” or “Submit invalid form”. Your coding agent writes the frames as HTML and sets the links. If your app already runs and you agree to send screenshots, it can instead capture one screenshot per state with a script on your machine, and the links between captured states are copied when you import them into the prototype. Links stay inside one app, so the web app and the admin panel each keep their own map. Concepts defines frames, states and flow links, and the canvas shows how the arrows appear.
For flows you design from scratch, such as a first-run experience, see how to prototype an onboarding flow with an AI agent.
A checklist before you share the diagram
- One task per diagram, with a named entry point and a named goal.
- Every node is a state of a screen, not a page.
- Every arrow has a trigger: a user action or a system event.
- Loading, empty, error and success states appear wherever they can happen.
- Each error state has a way out that keeps what the user typed.
- Steps outside the product (email, SMS, another device) are nodes too.
- No dead ends, no unreachable states.
- Cancel and back are drawn, not assumed.
A user flow diagram built from states is longer than a page diagram, and that is the point: the extra boxes are decisions you make once, on the map, instead of many times in code.
Frequently asked questions
What is the difference between a user flow and a user journey?
A user flow shows the screens and actions inside your product for one task, such as resetting a password. A user journey is wider: it covers the whole experience of the person, including steps outside the product, like reading an email or asking a colleague.
Should a user flow diagram include error states?
Yes. Errors, empty results and loading are where users get stuck, so each one that can happen on the path should appear as its own node, with the action or event that leads to it and the way out of it.
What tool should I use to draw a user flow diagram?
Any tool that draws boxes and labelled arrows works. The unit matters more than the tool: draw screen states rather than pages, and write every arrow as the action that causes the change. A plain text table in your repository is often enough to start.
Try it on your own app
Tell Claude Code one sentence. It creates the project and gives you a link to see your screens.
Tell Claude Code:
Connect this project to agentappbuilder.com and show me its screens.