User stories are supposed to be the bridge between "what customers need" and "what engineers build." In practice, they're usually the weakest link in most product-engineering workflows. They're either:
- Too vague ("as a user, I want to save time") — engineers don't know what to build
- Too detailed (5 pages with wireframes and edge cases) — you've written a spec, not a story
- Feature-list wrapped in story format ("as a user, I want a settings page") — describes UI, not need
- Missing acceptance criteria — engineers ship something you didn't want and everyone's confused
The good news: writing user stories well is a specific, learnable skill. Not intuitive, but not hard either. Here's the exact template that works, plus the 5 mistakes to avoid.
First: what user stories ARE (and what they're not)
User stories ARE:
- A shared understanding between product and engineering of WHAT to build and WHY
- The smallest unit of user-facing value that could ship independently
- A conversation starter, not a complete spec
- Written for engineers, testers, designers, and product to all understand
User stories ARE NOT:
- Detailed specs (specs are separate documents when needed)
- UI mockups (designs are separate artifacts)
- Feature lists (features are groupings of stories)
- Requirements documents (those are for enterprise contracting)
The single most common mistake: treating user stories as a checklist of features to build. That misses the point. Stories exist to communicate the USER'S NEED, so engineers can propose the best technical solution.
The template (the "Connextra format" — with additions that matter)
The canonical user story template is:
As a [role],
I want [action/capability],
So that [benefit/outcome].
Example: > As a restaurant owner, > I want to see which menu items sold most last week, > so that I can plan next week's inventory more accurately.
This is fine for the header. But by itself it's not enough — you need 3 more sections:
Full template
STORY HEADER:
As a [role],
I want [capability],
so that [outcome].
CONTEXT (2-3 sentences):
Brief background on why this matters now. What triggered this?
What's the current workaround if any?
ACCEPTANCE CRITERIA:
Given [starting state],
When [user action],
Then [expected result].
[Repeat for 3-5 scenarios]
NOTES / OUT OF SCOPE:
- Explicit list of what this story does NOT include
- Any technical or business constraints the engineer should know
- Design mockup link (if it exists) — but story stands alone without it
That's it. If your stories consistently include those 4 sections, they'll be buildable.
A specific example: good vs bad
Here's the SAME feature written badly and well.
Bad version
Title: "Analytics dashboard for restaurant owners"
Description: "We need to build an analytics dashboard so restaurant owners can see how their business is doing. It should show sales, popular items, hours, and staff performance."
Problems:
- What's the specific user need? "See how business is doing" is too vague
- No acceptance criteria — how does the engineer know what "done" looks like?
- "Sales, popular items, hours, staff performance" is 4 different stories, not one
- Missing context — why now? What's the current state?
Good version
Story header: > As a restaurant owner reviewing my week, > I want to see which menu items sold the most (by count and revenue) last week, > so that I can plan next week's inventory and adjust which specials to promote.
Context: > Owners currently do this in Excel by exporting POS data and manually summing. It takes 30-60 min per week and errors are common. This is the #1 request from our onboarding calls.
Acceptance criteria: > Given a restaurant owner logged into the dashboard, > When they navigate to "Week Summary," > Then they see a table of menu items sorted by units sold last week (Mon-Sun), > with columns for: item name, units sold, total revenue, average price per unit. > > Given the same view, > When they toggle "Sort by revenue," > Then the table re-sorts by total revenue descending. > > Given no sales data for the previous week (new restaurant, off-week), > When they load the view, > Then they see an empty state saying "No sales data yet — data will appear after your first week of orders."
Notes / out of scope: > - This story is JUST last week (Mon-Sun). Filtering by custom date ranges is a separate story. > - Item-level details (customer demographics, time-of-day patterns) are NOT included here. > - Design mockup: [link] > - Data source: existing orders table with menu_item_id foreign key.
Now an engineer can build this. The scope is clear, the "done" state is testable, the out-of-scope is explicit.
The 5 mistakes that make stories useless
Mistake 1: The "as a user" story
Any story that starts with "As a user, I want..." is too vague. "User" isn't a role. Real roles are specific: "restaurant owner," "new signup on trial," "admin managing team members," "returning customer on mobile."
Fix: name the specific role, and if that role has meaningful sub-segments (new vs experienced, admin vs member), separate stories for each.
Mistake 2: The feature-disguised-as-story
Story: "As a user, I want a settings page, so I can change my preferences."
Problem: "settings page" describes UI, not need. What preferences? Why do they need to change them? Which one specifically triggered this request?
Fix: decompose into real needs. "As a returning user, I want to change my notification email address, so notifications reach the right inbox after I switch jobs" — that's a real story. The settings page is a container for many stories.
Mistake 3: Acceptance criteria that aren't testable
Bad AC: "The dashboard should be fast and easy to use."
Problem: "Fast" and "easy" aren't testable. A tester can't verify this passed or failed without subjective judgment.
Fix: specific and measurable. "Given a restaurant with 100+ orders in the last week, when the dashboard loads, then it renders within 2 seconds and shows all rows without pagination."
Mistake 4: Acceptance criteria that only cover happy path
Bad AC: only "given a normal user with data, when they click X, then Y happens."
Problem: what happens for edge cases? New users with no data? Users on slow connections? Users who lose network mid-action?
Fix: every story should have AC for 3-5 scenarios, including at least 1-2 edge cases: empty state, error state, slow state, or unusual data shape.
Mistake 5: Bundling too much into one story
Bad story: "As an owner, I want a complete analytics dashboard with sales, staff performance, inventory, marketing metrics, and financial reports."
Problem: this is 6+ months of work, not a story. It can't ship independently. It'll get stuck in perpetual "in progress."
Fix: each story should be independently shippable in 3-10 days of engineering work. Break the big vision into small stories. Ship them one at a time. Get feedback. Iterate.
The INVEST framework (what makes a good story)
Every good story is INVEST:
- Independent — can ship without depending on other stories
- Negotiable — details can be discussed and refined, not set in stone
- Valuable — delivers user or business value
- Estimatable — engineering can estimate the work
- Small — 3-10 days of engineering effort max
- Testable — clear acceptance criteria that can be verified
If your story fails any of these tests, refactor it.
The story-writing process
Here's the actual workflow that produces good stories:
Step 1: Start with the WHY. Before writing anything, be able to answer: "What specific problem does this solve, for whom, and what's the current workaround?"
If you can't answer that, you're not ready to write the story. Do customer research first.
Step 2: Draft the header. Write the "As a [role], I want [X], so that [Y]" sentence. Get it approved by product and design before going further.
Step 3: Add context and acceptance criteria. Once the header is agreed, add the details. This is often where design mockups and technical constraints get incorporated.
Step 4: Explicitly declare out-of-scope. For every story, list what you're NOT doing. This is where scope creep gets prevented before it starts.
Step 5: Refine with engineering. Before the story enters the sprint, engineering reviews it. They may ask clarifying questions, suggest tech constraints, or push back on scope. Great — that's the point. The story is a starting point for the conversation, not the end of it.
Step 6: Update the story as you learn. As you build, you'll find things the story didn't anticipate. Update it. The story is a living document, not a set-in-stone requirement.
Related artifacts (not the same as stories)
Stories exist in a broader product ecosystem:
- PRDs: describe the WHY of a feature. Stories break the PRD down into shippable units.
- Epics: groupings of related stories that together deliver a larger initiative. "Analytics dashboard" is an epic; individual charts within are stories.
- Design specs: visual and interaction details. Stories reference the design but stand alone without it.
- Technical specs: implementation details for complex stories. Stories say WHAT; tech specs say HOW.
- Test plans: how to verify the story is working. Derived from acceptance criteria.
Confusing these is a common source of workflow friction. Stories are the connective tissue, but they don't replace any of the other artifacts.
The AI-era addition
If you're handing stories to AI coding assistants (Claude, Cursor, GitHub Copilot), the exact same template works. But add these two things:
1. Preferred stack context: "Build using [our stack]. Match the pattern in [reference file if applicable]. Never introduce a new dependency without approval."
2. Guardrails: "When you have ambiguity about a decision — for example, whether an edge case matters — pause and ask, don't guess. When you make a technical decision that's not obviously required by the story, add a brief comment explaining your reasoning."
AI assistants are better at following clear stories than humans (they can't push back socially). But they're worse at spotting ambiguity. The guardrails compensate.
If AI-assisted development is core to your process, the AI coding tools playbook covers this in more depth.
The one-page cheat sheet
For quick reference:
Story = As a [specific role], I want [capability], so that [outcome].
Every story needs:
- Header (3 lines above)
- Context (2-3 sentences: why now?)
- 3-5 acceptance criteria (Given/When/Then format)
- Explicit out-of-scope list
Every story should be INVEST (Independent, Negotiable, Valuable, Estimatable, Small, Testable).
Every story should be shippable in 3-10 days of engineering.
Never start a story with "As a user." Name the specific role.
Never write acceptance criteria without test cases for edge cases.
Always list what's OUT of scope explicitly.
A specific example
I worked with a startup where engineering and product were in constant friction. Every sprint, engineering would build something, product would say "that's not what I meant," and half the sprint's work would need rework.
What we found: their user stories were the header only, no acceptance criteria. Engineers were guessing at 40% of the details.
What we changed: implemented the full template above. Every story before sprint planning required all 4 sections, reviewed by engineering.
Results over 60 days:
- Rework dropped from ~40% of sprint capacity to ~10%
- Sprint predictability improved (engineers could estimate more accurately)
- Product-engineering meetings dropped 30% (fewer "wait, what did you mean?" conversations)
- Team morale up meaningfully — nothing kills morale like building the wrong thing
Same team, same skill, same product. Just better stories.
What to do this week
If you write stories currently:
- Take your last 5 written stories. Do they have all 4 sections (header, context, AC, out-of-scope)?
- Rewrite the weakest one using the template. Notice the difference.
If you don't write stories:
- Pick ONE upcoming feature. Write it as a story using the template.
- Show it to your engineer(s). Ask: "Is this clear enough for you to build?"
- Iterate based on their feedback.
If your engineers keep building "the wrong thing":
- The issue is almost never the engineers
- It's almost always ambiguous stories
- Improving story quality is the highest-ROI change you can make
If you're using AI coding tools:
- The template above works even better with AI (AI follows clear specs more reliably than humans)
- Add the two guardrails at the end (preferred stack + ambiguity handling)
If your team's ambition to build outstrips your ability to specify, related reads:
- How to write a PRD — the bigger structural document that stories break down from
- How to interview a product manager — if you're hiring for PM, story-writing skill is testable
- Shipping real products with AI coding tools — same story discipline, applied to AI-assisted workflows
User stories are the single most under-invested-in artifact in most product organizations. Investing 30 minutes to write a good story often saves days of rework. Do the math.
---
If your team's stories aren't landing, reach out via the contact page with a paragraph about the situation and I'll help diagnose whether the issue is story quality, review process, or something else.
