aa.
All writing
  • Requirements
  • Project Management
  • Agile

How to Write User Stories and Acceptance Criteria

Turn a client's idea into requirements developers can build: the user story format, acceptance criteria examples, non-functional requirements, and a checklist.

· 6 min read

A tangled glowing amber scribble connected by a single line to a neat stack of four cards, each with a check mark

A client says: "We need a dashboard for our team." That sentence can mean a week of work or three months. The difference lies in the requirements, and in whether the developers who build it understand them the same way the client does.

As a technical project manager, I sit between the client and the team, and when a request isn't clear, I set up a discovery meeting with the client rather than let the team guess. This article is the approach I use and recommend for turning that conversation into requirements developers can actually build from.

The short answer

Good software requirements describe who needs what and why, define how everyone will know it's done, and answer the questions a developer would otherwise have to guess. In practice that means user stories, testable acceptance criteria, edge cases, non-functional requirements, and a short readiness check before work starts.

Start with the problem, not the feature

Before writing anything, understand the problem behind the request:

  • Who will use this, and how often?
  • What are they doing today instead?
  • What does success look like for the client?

Often the best solution is smaller than the original request. Sometimes it's different entirely.

User story format

A user story keeps the focus on the user and the value. The most common format, popularised by Agile teams since the early 2000s, is:

As a [type of user], I want [an action], so that [a benefit].

For example: As a team lead, I want to see each project's open blockers on one screen, so that I can act on them before they delay delivery.

The "so that" part matters. It tells developers what's important when they have to make small decisions on their own.

A quick quality check is INVEST, a checklist coined by Bill Wake: a good story is Independent, Negotiable, Valuable, Estimable, Small, and Testable. If a story fails "Small" or "Estimable", split it.

Acceptance criteria (with examples)

Acceptance criteria define when a story is done. They should be specific, testable, and agreed with the client before development starts. Two common styles:

1. Given / When / Then (the Gherkin format used in behaviour-driven development):

Given a project has blocked tasks When the team lead opens the dashboard Then each project shows the number of blocked tasks, and clicking the number lists them

Given sets up the starting situation, When is the action, and Then is the result you can observe.

2. A simple checklist, which works well for straightforward stories:

  • Projects are sorted by number of blocked tasks, highest first.
  • Projects with no blocked tasks show "0" rather than being hidden.
  • Only team leads and project managers can see the dashboard.

Either way, good acceptance criteria become QA's test cases. If a criterion can't be tested, it isn't finished.

Cover the edge cases

Most questions developers ask are about what happens when things aren't normal:

  • What if there's no data yet (empty states)?
  • What if the input is invalid or too long?
  • What if the network fails or the user has no permission?
  • What happens on mobile?

Listing these upfront prevents most "we didn't think about that" moments late in the project.

Functional vs non-functional requirements

Functional requirements describe what the system does: "the team lead can see blocked tasks per project". User stories and acceptance criteria mostly cover these.

Non-functional requirements describe how well the system does it, and they're the ones most often forgotten:

  • Performance: "the dashboard loads in under two seconds for 50 projects".
  • Security and permissions: who can see or change what.
  • Reliability: what happens if a third-party service is down.
  • Compatibility: browsers, devices, and screen sizes to support.
  • Accessibility: for example, keyboard navigation and readable contrast.

Alongside these, a buildable requirement usually needs a few technical notes: the data to store or show, integrations involved, and links to designs. This is where a developer background helps: you can anticipate the questions before they're asked.

Separate must-haves from nice-to-haves

Not every requirement is equally important. MoSCoW prioritisation sorts them into Must have, Should have, Could have, and Won't have this time. It comes from the DSDM framework, whose guidance is to keep must-haves to no more than about 60% of the effort, so there's room to absorb surprises. It makes trade-offs easier when time runs short, and visible to the client.

Use a Definition of Ready

Before a story goes into a sprint, check that it's ready to build. The Scrum Guide doesn't define a "Definition of Ready"; it's a practice many teams add for themselves. A simple version:

Stories that aren't ready go back for clarification instead of into development. Keep it lightweight: a Definition of Ready should prevent guesswork, not become a gate that stops all work.

Keep requirements alive

Requirements change as everyone learns. When they do:

  • update the story in the tracker, not just in a chat message,
  • note what changed and why,
  • treat significant additions as change requests with an estimate and timeline impact.

AI tools can help here too, for example by turning meeting notes into a first draft of user stories and acceptance criteria, but the result always needs review with the client. I wrote more about that in AI in Project Management.

Frequently asked questions

What is the user story format?

The common format is "As a [type of user], I want [an action], so that [a benefit]." It names who needs the feature, what they want to do, and why it matters. The "so that" part is the most important, because it explains the value and guides developers when they make small decisions on their own.

What is the difference between acceptance criteria and the Definition of Done?

Acceptance criteria are specific to one user story: the conditions that story must meet to be accepted. The Definition of Done applies to every piece of work, for example code reviewed, tested, and deployed to staging. A story is complete only when it meets both its own acceptance criteria and the shared Definition of Done.

What is the difference between Definition of Ready and Definition of Done?

The Definition of Ready is a checklist a story must meet before development starts, such as agreed acceptance criteria and identified dependencies. The Definition of Done is the quality standard work must meet to be considered finished. Ready protects the start of the work; Done protects the end. Only Done is part of the Scrum Guide.

What are functional and non-functional requirements?

Functional requirements describe what the software does, such as letting a user reset their password. Non-functional requirements describe how well it does it: performance, security, reliability, compatibility, and accessibility. Both need to be written down, because non-functional requirements are the ones most often missed until late in a project.

Final thoughts

Developers can build almost anything that's clearly described. The project manager's job is to make sure it is: clear problem, clear outcome, clear edge cases, written down and agreed.

Related: Why Software Projects Get Delayed and How to Estimate Software Development Time.