How to write user stories that actually get done

Introduction

At each stop in my career, I seem to develop a reputation for being a Fussy Franey with user stories. I've seen some eye rolls when I've asked for one story to be broken into three, and I've faced incredulity when pointing out that one "user story" is actually an entire epic—or even so broad in scope that it could be an entirely separate business.

I like to get things done, and I've found that small, well-written user stories are the single biggest enabler of dev velocity.

User stories should be small

Very small. How small?

They should encompass a single user interaction, single visual element, or single application reaction.

Reducing scope for a feature or launch should not require rewriting user stories

What counts as a user interaction?

What counts as a visual element?

Viewing is an action, and seeing a visual/UI element counts as a user story. Visual elements can be tiny, too, like a red notification dot you might see on a new menu link.

It might seem like overkill to have an entire user story for a notification dot, but the menu item can exist without the notification dot. Because the notification dot depends on the menu item, it can be implemented separately from the menu item and prioritized separately, too.

What counts as an application reaction?

An application reaction is a change in the application that happens as a result of a user action or as a result of other application logic. The reaction could take place within an application (a toast notification) or across applications (sending an SMS).

Some quick examples:

Q: When is a story not a story?

A: When it's an epic!

For example, let's take the following story:

As a user, I can delete a to-do item

Sounds like a small, regular story, right? Not so fast.

A story like that could have a number of requirements before it could be considered done (optional requirements marked with asterisks):

  1. Showing a confirmation modal when clicking the delete button*
  2. Writing the API delete endpoint
  3. Performing the API delete request on click
  4. Disabling the button while the request is processing*
  5. Removing the to-do item on a success response
  6. Showing a success toast*

There's a lot happening there. There's enough happening here to make deleting a to-do item an epic rather than a single story.

And what's an epic? An epic is "a large, high-level piece of work" (ScrumAlliance) that consists of multiple user stories and other pieces of work, like non-user-facing dev tasks.

Atlassian has a helpful explanation of epics as a strategy to break down work into smaller pieces:

Epics are a helpful way to organize your work and to create a hierarchy. The idea is to break work down into shippable pieces so that large projects can actually get done and you can continue to ship value to your customers on a regular basis. Epics help teams break their work down, while continuing to work towards a bigger goal. (Atlassian, "Agile epics: definition, examples, and templates")

In other words, an epic captures an entire feature flow, like the end-to-end (and frontend-to-backend) process of creating a to-do item, and it consists of one or more user stories and/or dev tasks.

Can stories have multiple acceptance criteria?

They can!

But they still need to be small, and the acceptance criteria need to be so intimately related that separating them would be impossible to implement or impossible to verify. So what is a story that can have multiple acceptance criteria? The second requirement in the epic above is a good example:

As a user, I can confirm whether I want to delete a to-do item

This story might have acceptance criteria like the following:

  1. GIVEN I am a user viewing a to-do item

    WHEN I click the delete button

    THEN I am shown a confirmation modal

  2. GIVEN I am a user confirming whether to delete a to-do item

    WHEN I click the close button on the confirmation modal

    THEN the modal is closed AND the to-do item is not deleted

  3. GIVEN I am a user viewing the delete to-do confirmation modal

    WHEN I confirm my intent to delete the to-do item

    THEN the item is deleted AND the modal is closed

Showing a confirmation modal (application reaction) when clicking the delete button (user action) encompasses two UI elements and one action+reaction, but still makes sense to have in the same user story because there's no way to validate that the delete button behaves as expected without having a confirmation modal to view.

The story could be broken into subtasks to parallelize development by creating a subtask for the design of the confirmation modal. Ideally, the confirmation modal would be reusable and wouldn't have to be implemented separately for each action. For more on this, see the "User stories should be new" section below.

User stories should be explicit

A story's definition of "done" should be unambiguous.

Acceptance criteria should be specific and comprehensive, and it should be described in writing rather than being hidden in designs.

If a story involves changing text, for example, include the old and new text in the acceptance criteria. When acceptance criteria read something like "Update wording to match designs", changes are easy to miss, which can throw off estimates and lead to QA rejections.

User stories should be new

Existing capabilities can be acceptance criteria, while new capabilities should be user stories.

If you have a form component that shows an error message on a 500 response, for example, there doesn't need to be a new user story to use this behaviour in a new form. For another example, if you have a phone number field and you want to see a phone number input on a mobile device, because this is a built-in capability of an <input type="tel">, it doesn't need to be its own user story.

Lightning summary ⚡

While it may seem tedious to have stories with such a narrow scope, large user stories often mask complexity in a project, posing challenges to estimating, sequencing, QAing, and descoping work.

User stories that actually get done are small, explicit, and new.