What a User Flow Is (and What It Is Not)
A user flow is a step-by-step map of how a person completes a specific task in your app, from a starting point to a successful end state. It focuses on actions, decisions, and system responses. A good user flow answers: “What does the user do next?” and “What happens if something goes wrong?”
User flows are not the same as a screen list or a sitemap. A screen list tells you what screens exist; a user flow tells you how a person moves between them to accomplish a goal. User flows are also different from UI mockups: mockups show what a screen looks like; flows show the sequence and logic that connects screens and states.
When you plan user flows for key tasks, you reduce confusion, prevent missing states (like errors and empty screens), and make sure the app supports real-world behavior (like changing your mind, losing connection, or needing help).
Why User Flows Matter for Beginners
Beginners often design “happy path only” experiences: everything works, the user never makes mistakes, and the app always has data. In reality, users forget passwords, mistype addresses, deny permissions, and abandon tasks halfway through. User flows force you to plan for these realities.
User flows also help you communicate with others. If you work with a developer, a flow clarifies what needs to be built and in what order. If you work alone, it becomes your checklist for implementation and testing.
- Listen to the audio with the screen off.
- Earn a certificate upon completion.
- Over 5000 courses for you to explore!
Download the app
Key Parts of a User Flow
1) Trigger (Entry Point)
The trigger is what starts the task. Examples: tapping “Sign up,” receiving a push notification, clicking “Add to cart,” or opening the app for the first time.
2) Steps (User Actions)
These are the actions the user takes: typing, tapping, selecting, scanning, uploading, confirming.
3) System States (App Responses)
After each action, the app responds: loading, success, error, empty state, permission request, confirmation message.
4) Decisions (Branches)
Decision points create branches: “Has an account?” “Payment succeeded?” “Permission granted?” Each branch should lead somewhere sensible.
5) End State (Success and Alternate Endings)
The end state is the outcome. You should define at least: a success end state (task completed) and one or more alternate endings (user cancels, fails, or postpones).
Choosing “Key Tasks” to Flow
You do not need flows for everything at once. Start with tasks that are essential to the app working and that users will do frequently. Typical key tasks include:
- Onboarding and account creation (or guest entry)
- Login and logout
- Searching or browsing to find something
- Creating the main object in your app (a post, booking, order, note, request)
- Paying or subscribing (if applicable)
- Editing or deleting the main object
- Getting help, reporting an issue, or contacting support
As you draft flows, keep each flow focused on one task. If you notice you are mixing tasks (for example, “search + purchase + referral”), split them into separate flows and connect them with references.
Levels of Detail: High-Level vs. Detailed Flows
You can represent a user flow at different levels:
- High-level flow: A simple sequence of steps and screens. Useful for early planning and alignment.
- Detailed flow: Includes validations, error states, permission prompts, loading states, and alternate paths. Useful for implementation and QA.
A practical approach is to start high-level, then expand only the most important flows into detailed versions.
How to Write a User Flow Step-by-Step
Step 1: Name the task in a user-centered way
Use a verb + object format. Examples: “Create an account,” “Book an appointment,” “Save a recipe,” “Send a message.” Avoid vague names like “Onboarding flow.”
Step 2: Define the start and success end state
Write one sentence for each:
- Start: “User is on the home screen and wants to…”
- Success: “User sees confirmation that…”
This keeps the flow bounded and prevents scope creep.
Step 3: List the happy path steps
Write the simplest successful sequence. Keep steps atomic (one action per step). Example: “Tap ‘Add’” rather than “Add item and confirm.”
Step 4: Add decision points and alternate paths
Ask “What could be different here?” Common branches include:
- User already has an account vs. new user
- Required field missing vs. complete
- Network available vs. offline
- Permission granted vs. denied
- Payment success vs. failure
- Item in stock vs. out of stock
Step 5: Add system feedback and states
For each step, note what the user sees after acting: loading indicator, inline validation, toast/snackbar, error message, confirmation screen, email verification notice.
Step 6: Check for “escape hatches”
Users should be able to cancel, go back, save progress, or postpone when reasonable. Identify where “Back,” “Cancel,” “Save draft,” or “Skip” should exist.
Step 7: Validate the flow against real constraints
Consider device and platform constraints: permission prompts, biometric login availability, deep links, and interruptions (incoming call, app backgrounded). Decide what happens when the user returns.
A Simple Notation You Can Use
You can document flows in plain text using arrows and brackets. This is beginner-friendly and works even before you use diagram tools.
Start: Home screen (logged out) -> Tap “Sign up” -> Enter email + password -> Tap “Create account” -> [Loading] -> Success: Account created + user lands on dashboardFor branches, use indentation or labels:
Tap “Create account” -> [Loading] -> If email already used: show error + offer “Log in” -> Login screenExample 1: Account Creation Flow (with Common Branches)
This example shows how to expand a basic sign-up flow into a more realistic one. You can adapt it whether your app uses email/password, phone OTP, or social login.
Happy path (email + password)
Start: Welcome screen (logged out) -> Tap “Create account” -> Sign-up screen -> Enter email -> Enter password -> Tap “Create account” -> [Loading] -> Success: Account created -> Optional: Profile setup screen -> DashboardAdd validation and error handling
Now add the most common failure points:
- Invalid email format: Inline message under email field; disable submit until valid or show error on submit.
- Weak password: Show password rules; provide strength indicator; allow “show password.”
- Email already in use: Offer a direct path to login and “Forgot password.”
- Network error: Show retry option; keep entered data.
Tap “Create account” -> If email invalid: show inline error; stay on sign-up screen -> user edits email -> retry submitTap “Create account” -> [Loading] -> If network fails: show “Couldn’t connect” + “Try again” -> stay on sign-up screen with fields preservedAdd decision points
Decisions often appear right after sign-up:
- Is email verification required?
- Is profile setup mandatory or skippable?
- Is the user allowed to proceed as a guest instead?
Account created -> If email verification required: show “Verify your email” screen -> user taps “Open email app” -> user returns -> Tap “I’ve verified” -> [Check status] -> DashboardNotice the return step: users leave the app to check email, then come back. Planning this prevents a common beginner mistake: assuming the user never leaves the app mid-task.
Example 2: Search and Select Flow (Finding Something)
Many apps rely on users finding an item: a product, an article, a restaurant, a workout, a contact. The flow should support both “I know what I want” and “I’m exploring.”
Happy path
Start: Home screen -> Tap search bar -> Enter query -> Results list -> Tap item -> Item details screenKey branches to include
- No results: Provide suggestions, filters, or a clear “Try different keywords.”
- Slow network: Show loading skeletons and allow cancel.
- Spelling mistakes: Offer “Did you mean…?”
- Filters/sorting: Let users refine results without losing the query.
Enter query -> [Loading] -> If no results: show empty state + suggested searches + “Clear filters”Also consider the back behavior: when the user returns from item details to results, they usually expect the same scroll position and filters to remain.
Example 3: Create and Publish Flow (Creating the Main Object)
In many apps, the core action is creating something: a post, a listing, a booking request, a note, a support ticket. This flow often needs drafts, validation, and confirmation.
Happy path (create a post)
Start: Feed screen -> Tap “New post” -> Compose screen -> Enter text -> Add photo (optional) -> Tap “Publish” -> [Uploading] -> Success: Post appears in feedAdd the real-world complexity
- Permissions for photos: If the user denies access, provide an alternative (take a photo, choose later, or continue without photo).
- Upload failures: Allow retry; keep the draft.
- Accidental exit: Confirm before discarding; offer “Save draft.”
- Content rules: If text is too long or missing required fields, show inline guidance.
Tap “Add photo” -> If permission not granted: show system prompt -> If denied: show explanation + “Open Settings” + “Continue without photo”Tap “Publish” -> [Uploading] -> If upload fails: show “Upload failed” + “Retry” + “Save as draft”Draft handling is often overlooked. Even a simple “Save draft locally” can dramatically improve the experience when connectivity is unreliable.
Example 4: Checkout/Payment Flow (If Your App Takes Money)
Payment flows require careful branching because failures are common and trust is critical. Even if you use a third-party payment sheet, you still need to plan the surrounding states.
Happy path
Start: Cart screen -> Tap “Checkout” -> Address screen -> Select delivery option -> Payment method screen -> Tap “Pay” -> [Processing] -> Success: Order confirmation screenImportant branches
- Out of stock / price changed: Inform user and update cart before payment.
- Payment declined: Let user try another method; explain next steps without blaming.
- 3D Secure / bank verification: User may leave the app or see an embedded verification step.
- Duplicate taps: Prevent double charges by disabling the pay button during processing.
Tap “Pay” -> [Processing, button disabled] -> If declined: show error + “Try another card” + “Contact support”Also plan what happens after success: should the user be able to view the receipt, track the order, or share confirmation? Those are follow-up tasks that may become separate flows.
Designing for Interruptions and Edge Cases
Even if you do not diagram every edge case, you should explicitly think through the most likely interruptions for each key task:
- App backgrounded: User switches apps mid-flow. When they return, do you restore the state or restart?
- Session expired: User is logged out during a task. Do you save progress and prompt login?
- Offline mode: Can the user continue and sync later, or must you block the action?
- Slow operations: Uploading, processing, syncing. Provide progress and avoid “frozen” screens.
A practical rule: for any step that can take more than a second, plan a loading state. For any step that can fail, plan a retry path that does not punish the user by deleting their input.
Flow Quality Checklist (Use This While Drafting)
- Single clear goal: The flow completes one task end-to-end.
- Obvious next step: At each point, the user knows what to do next.
- Minimal steps: Remove unnecessary confirmations and repeated data entry.
- Feedback: Loading, success, and error states are visible and understandable.
- Recovery: Errors have actionable fixes (retry, edit, choose another option).
- Consistency: Similar actions behave similarly across flows (e.g., save, cancel, back).
- State preservation: Returning to a previous screen does not unexpectedly reset progress.
- Accessibility considerations: Avoid flows that rely only on color, tiny tap targets, or time-limited actions without alternatives.
Turning Flows into Buildable Requirements
Once a flow is drafted, you can translate it into implementation-friendly notes. For each step, identify:
- Inputs: What data the user provides (text, selection, photo).
- Validations: What rules apply (required fields, formats, limits).
- API calls: What network requests happen and when.
- States: Loading, empty, error, success.
- Analytics events (optional): Track key milestones like “Checkout started” or “Post published.”
Example for a “Publish post” step:
Step: Tap “Publish” on compose screen Inputs: text (required), photo (optional) Validation: text length 1–280 API: POST /posts States: loading (uploading), success (navigate to post), error (retry + draft) Edge: offline -> save draft + show “Will upload when online”This format helps you avoid missing requirements and makes it easier to estimate effort.
Common Beginner Mistakes (and How to Fix Them)
1) Only drawing the happy path
Fix: Add at least three branches: validation error, network failure, and user cancellation/back.
2) Making flows too long
Fix: Split flows by task. If the user completes one goal and then starts another, create a new flow and link them.
3) Forgetting system prompts and permissions
Fix: For any feature that uses camera, photos, location, notifications, or contacts, add a permission decision: granted vs. denied.
4) Not defining what happens after success
Fix: Specify the post-success destination and available next actions (view details, share, track, edit, return home).
5) Losing user input on errors
Fix: Preserve form fields and drafts by default. Only clear input when the user explicitly resets.
Practical Exercise: Draft Two Key Task Flows in 30 Minutes
Exercise setup
Pick two tasks that are central to your app. For example: “Create an account” and “Create the main item.” Use plain text notation.
Step-by-step
- 5 minutes: Write start and success end state for each task.
- 10 minutes: Draft the happy path steps (aim for 6–12 steps).
- 10 minutes: Add branches: validation error, network error, cancel/back.
- 5 minutes: Add system states (loading, success message) and note any permissions.
When you finish, read each flow as a story. If you find yourself saying “and then the user somehow…,” that indicates a missing step or missing screen/state.