User Flows skill for Codex
Map every path, not just the happy one. Codex builds user flows from what the product really does, reading routes, redirects, guards and feature flags, then draws them as Mermaid flowcharts with entry points, decisions, system actions, error branches and exits. A gap review checks roles, re-entry, back behaviour and removable steps, and journey maps mark which pain points are evidence and which are assumptions.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- user-flows Installs to ~/.agents/skills/user-flows/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install user-flows The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project user-flows Installs to .agents/skills/user-flows/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/user-flows.zipunzip -o user-flows.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) user-flows PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $user-flows, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Maps user flows, task flows and customer journeys as Mermaid flowcharts and journey tables - entry points, screens, decisions, system actions, error branches and exits - derived from the actual routes, redirects and guards in the codebase or from a product brief. Flags dead ends, missing error paths and unnecessary steps. Use when asked to map, diagram or document a user flow, journey map, onboarding or checkout path, or to find gaps before building or redesigning a feature.
Use it when
- You need a diagram of how users move through a feature
- Planning a new feature and want every branch identified before building
- Documenting existing behaviour for onboarding a team or a redesign
- Looking for dead ends, missing error states or unnecessary steps
Use something else when
- You need screen layouts rather than the path between screens: use wireframing
- You are diagramming service-to-service calls and infrastructure: use c4-architecture-diagrams
How to check the result
The Mermaid renders without errors, and tracing each entry point in the running app or code reaches the same nodes, decisions and exits the diagram shows.
The mistake it prevents
Diagramming only the happy path, so declined payments, expired links and permission errors go undesigned until users hit them.
A useful flow diagram shows every way a real user enters, every decision that changes their path, what the system does in between, and where each path ends, including the failure paths. If the diagram has only the happy path, it documents the demo, not the product.
Pick the right artifact
| Need | Artifact | Granularity |
|---|---|---|
| How one user completes one task in the product | Task flow | Screens and decisions, single path with branches |
| All the ways users move through a feature | User flow | Multiple entry points, roles, error branches |
| Experience across channels and time, including feelings | Journey map | Stages x (actions, touchpoints, thoughts, pain, opportunities) |
| Which screens exist and how they nest | Site map / IA tree | Hierarchy, no decisions |
| Exactly what services call each other | Sequence diagram | System-level, for engineers |
Default to a user flow in Mermaid: it renders in GitHub, GitLab and most docs sites, it diffs in review, and Codex can keep it in sync with code.
Workflow
- Define the goal, the user (role, state such as logged-out or trial), and the trigger.
- List entry points: direct URL, email link, notification, deep link, in-app button.
- Derive screens and transitions from code or the brief.
- Add decisions, system actions, and error and edge branches.
- Mark exits: success, abandonment, handoff to another flow.
- Review for gaps; write findings.
- Save as
docs/flows/<flow>.md(or whereAGENTS.mdsays docs live).
Derive the flow from code
Read the real behaviour rather than trusting memory or the design file:
rg -n "path:|<Route|createBrowserRouter|app/.+/page\.(t|j)sx" src app 2>/dev/null | head -50
rg -n "redirect\(|navigate\(|router\.(push|replace)|useNavigate|NextResponse\.redirect" src app
rg -n "middleware|beforeEach|loader|requireAuth|isAuthenticated|guard" src app
rg -n "status\s*===?\s*['\"]|case ['\"][A-Z_]+['\"]" src | head # state machines and statuses
Each redirect or guard is a decision node. Each API call that can fail is an error
branch. Feature flags (rg -n "flag|isEnabled|variant") create alternative paths; note
which variant the diagram shows.
Notation
| Shape | Mermaid | Meaning |
|---|---|---|
| Stadium | A([Start: email link]) | Entry or exit |
| Rectangle | B[Pricing page] | Screen or view |
| Rhombus | C{Has account?} | Decision by user or system |
| Parallelogram | D[/Enters card details/] | User input |
| Subroutine | E[[Create Stripe customer]] | System action, not visible as a screen |
| Hexagon | F{{Email: welcome}} | Message sent outside the app |
| Dotted edge | -.-> | Optional or async path |
Label every edge leaving a decision. Keep one flow per diagram and under about 25 nodes;
split larger flows into linked diagrams with click or named subflows.
Example: trial signup
flowchart TD
start1([Pricing page CTA]) --> signup[Sign up form]
start2([Invite email link]) --> accept[Accept invite page]
signup --> s_in[/Email + password or Google/]
s_in --> exists{Email already registered?}
exists -- yes --> login[Log in page, email prefilled]
exists -- no --> create[[Create user + trial workspace]]
create -- API error --> err1[Form with error, input kept] --> s_in
create --> verify{{Email: verify address}}
create --> onboard[Onboarding step 1: workspace name]
verify -. clicks link later .-> verified[[Mark email verified]]
onboard --> invite{Invite teammates now?}
invite -- skip --> dash([Dashboard, empty state])
invite -- yes --> inv[/Enters emails/] --> sent[[Send invites]] --> dash
accept --> hasacct{Logged in?}
hasacct -- no --> login
hasacct -- yes --> join[[Add to workspace]] --> dash
login --> dash
Journey map table
For cross-channel experiences, use a table (Mermaid’s journey diagram is too limited
for pain points and opportunities):
| Stage | Discover | Sign up | First value | Habit |
|---|---|---|---|---|
| Actions | Reads comparison post | Creates account | Imports first CSV | Weekly report |
| Touchpoints | Blog, search | Web app | Import wizard | Email digest |
| Thinking | "Does it handle my data size?" | "Why do they need my phone?" | "Did it work?" | "Is this still accurate?" |
| Pain | No pricing for large teams | Phone field required | No progress for 40 s | Digest lands at 3 a.m. local |
| Opportunity | Add volume pricing table | Make phone optional | Progress bar + row count | Send in user's timezone |
Base thoughts and pain points on evidence (support tickets, analytics funnels, research notes) and say which ones are assumptions.
Gap review
Walk every path and ask:
| Check | Typical gap |
|---|---|
| Every decision has all branches | “Payment declined” or “email taken” missing |
| Every system action has a failure branch | Timeout during account creation |
| No dead ends | Error page with no way back; empty state with no action |
| Re-entry works | User leaves mid-flow and returns from email: where do they land? |
| Roles and states | Logged out, unverified, trial expired, no permission, invited user |
| Steps that can be removed | Confirm-password field, separate “review” step with no edits |
| Back behaviour | Browser back mid-wizard loses data or repeats a payment |
| Cross-device | Link opened on phone after starting on desktop |
Count steps on the happy path (screens plus required inputs). Each step that does not change the outcome is a candidate for removal or defaulting.
Verification
- Render the Mermaid: paste into a Markdown preview, or run
npx -p @mermaid-js/mermaid-cli mmdc -i flow.mmd -o flow.svg(needs network to install). - Trace the diagram against the running app or the code once per entry point; every node must correspond to a real route, component or call.
- Confirm decision labels match real conditions in code (for example the redirect when
!user.emailVerified).
Output template
# Flow: <name>
Goal: <what the user wants> User: <role/state> Variant: <feature flag or version>
Entry points: <list>
Success exit: <where the user ends up> Other exits: <abandon, handoff>
<mermaid diagram>
## Findings
| # | Gap or friction | Where | Severity | Suggestion |
|---|---|---|---|---|
| 1 | No branch for declined card | Checkout payment | High | Inline error, keep cart, offer other method |
## Step count
Happy path: <n> screens, <m> required inputs. Proposed: <n'>, <m'>.
## Assumptions
<paths inferred without code or data evidence>
Related: evaluate the screens in the flow with $usability-heuristics; sketch new
screens with $wireframing.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "User Flows"
short_description: "Map every path, not just the happy one"
default_prompt: "$user-flows Map the signup and onboarding flow from our Next.js routes as a Mermaid diagram" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.