1. Courses
  2. Developer Foundations
  3. Software Development: Idea to App
  4. Stop 1

30 minBeginner

From idea to one-page spec

Every app starts as a sentence in someone's head, and most of the wasted weeks in software come from building that sentence before anyone has pinned it down. This lesson turns an idea into one page that says who the app is for, what problem it solves, how you will know it worked, what it will not do, and the smallest version worth building first. That page drives every later stage of this course.

By the end you can

  • Turn an idea into a problem statement with a named user and real evidence
  • Write goals with a baseline, a target and a date, plus one guardrail
  • Write non-goals that stop work, each with a reason
  • Cut a wish list down to the smallest useful version that fits a time budget
  • Keep a one-page spec in your repository, with acceptance checks and a small script that checks it

The everyday picture

Picture someone opening a food stall near a busy bus station. She could start with a menu of twenty dishes, card payments, delivery and a loyalty card. Or she could write one card first. Who will eat here? Office workers with twenty minutes for lunch. What do they need? A hot meal, fast, for a fair price. How will she know it works? She sells 80 plates by 2 pm on most days of the first week. What will she not do yet? No delivery and no card machine, because she cannot afford either until she knows people come back.

Her smallest useful version is one good rice dish, one drink and a queue that moves. It is small, and it is complete: a customer can arrive hungry and leave fed. After a week she knows more than any plan could tell her, and she adds the second dish because people asked for it. A one-page spec is that card, written for an app.

From an idea to a problem with evidence

Ideas usually arrive as solutions. "Let's build a reorder app." "Add AI suggestions." A solution hides the question that matters: what is going wrong today, for whom, and how do we know? If you start building the solution, you cannot tell later whether it helped, because nobody wrote down what "helped" means.

So the first part of the page is a . Write it in four parts:

  • Who: one kind of person, named by role. "Owners of small partner shops", not "users".
  • What they are trying to do: the job, in their words. "Order next week's stock."
  • What goes wrong today: the delay, the mistake or the cost. "They phone the same order in every week, and some phone orders arrive wrong."
  • How we know: at least one number and one quote. Numbers show size; a quote shows the reason behind the number.

Then test the statement. Could a different solution fix the same problem, such as a printed order form or a saved order the sales rep keeps? If yes, good: you have described a problem, and your app is one of several ways to solve it. If the statement only makes sense with your app in it ("shops lack a reorder app"), you wrote the solution twice. Problems before solutions has more ways to find the problem behind a request.

Next, the users. Name the , the one person whose job the first version must make easier. Then list who else is touched: people whose work changes, the person who decides, and the team who will run or rebuild it later. For each primary user, write the context that changes your design: the device, the network, the time of day and the pressure they are under. "Orders after closing time, on a cheap Android phone, on patchy mobile data" will shape your screens, your timeouts and your tests far more than an age range would.

Evidence does not need a research project. Order data you already have, plus five short conversations with real users, is usually enough to write this section with confidence. User interviews that don't lie shows how to ask about what people did last week instead of what they might like.

Quick check

Which line is a problem statement, and not a solution in disguise?

Goals you can measure, non-goals that stop work

A goal describes a change in what people do, with numbers. Each goal needs five things: a metric, a (where it is today), a target, a date, and where the number comes from. If any one is missing, the goal will start an argument at the end instead of settling one.

For a small first version, pick a metric that can move in weeks with a handful of users. A company-wide number, such as the share of all partner orders placed in the app, matters, but a pilot with 20 shops barely moves it, so you would learn nothing. Choose a number about the pilot group itself: "the share of pilot shops' orders placed in the new app, from 0% to 40% by the end of week 4, counted in the order table". OKRs and outcome goals goes deeper on picking outcome metrics.

Add one : something that must not get worse while you chase the goal. A reorder app that gets more orders in but doubles the number of wrong deliveries has failed. "Corrections after delivery stay at 1 in 12 or better" protects the people at the other end of your app.

Then write the . A non-goal is something a reasonable person could expect the app to do, which you have decided it will not do yet, with the reason. Non-goals do two jobs. They stop a stakeholder from waiting for a feature that is not coming, and they stop you, the builder, from adding it on a quiet afternoon. "The app will not be slow" is not a non-goal; nobody planned a slow app. "No payments in the app, because invoices stay on today's process" is one: people will ask about it, and now the answer is written down.

A written reason also lets you reopen a non-goal when the reason changes. Writing specs people read covers goals, non-goals and open questions for larger specs.

Quick check

A 20-shop pilot will run for four weeks. Which goal will tell you, at the end, whether the first version worked?

The smallest useful version

With the problem and goals written, list what the first version will do. This is where most beginner projects go wrong. The list grows to fifteen features, and when the time runs out nobody can use the app for anything.

The fix is a method in three steps.

  1. Set the time budget first. Decide how much time the problem is worth before you list features: for example, three weeks for one developer. Basecamp's Shape Up method calls this the . An estimate asks how long the features will take; an appetite asks what you can build in the time the problem deserves. The time stays fixed and the scope changes to fit.
  2. Write the user's journey as steps. For a reorder app: sign in, see last orders, repeat one with changes, see its status, see a weekly summary. These steps are the backbone. Every step the user needs to finish the job must exist in the first version, or the job cannot be done at all.
  3. For each step, pick the cheapest version that works. Sign-in can be a simple pilot login before it is a full account system. "Last orders" can be the newest five, with no search or filters. The summary can be one screen of numbers. Each step is basic, and together they let a real user finish the real job.

The result is a : a basic version of every step, built through every layer of the app, from screen to API to database. The opposite is building layer by layer, or step by step to a polished finish. Both feel productive, and both can leave you with nothing a user can try. The first diagram shows the difference.

People often call this a minimum viable product (MVP). The word "minimum" tempts teams to ship something too thin to teach them anything, so this course says smallest useful version: small enough to fit the appetite, useful enough that a real user does the real job with it, and complete enough that you can measure the goal.

Everything you cut goes into one of two lists. Later is for ideas you might build after you learn from the pilot. Never in this version is your non-goals. Writing cut ideas down makes cutting easier, because nothing is lost.

Quick check

You have three weeks. Which plan gives a shop owner something to try at the end?

Sign in Last orders Repeat and edit Order status Weekly summary A. Polished, one by one built, polished built, polished not yet not yet not yet Week 3: nobody can order B. Every step, basic basic basic basic basic basic one journey, end to end Week 3: a shop reorders
The same three weeks, spent two ways. Building step by step to a polished finish (A) leaves the repeat, status and summary steps unbuilt, so nobody can place an order. A thin slice (B) builds a basic version of every step, so a shop owner can do the whole job and you can measure the goal.

From spec to plan: acceptance checks, risks and open questions

A list of features says what the app has. It does not say when each feature is done. For that, give every item in the smallest version one to three , written as Given, When, Then:

  • Given a shop's last order had 18 lines, when the owner taps Repeat, then a draft opens with the same 18 lines and quantities.
  • Given an item is no longer sold, when the owner repeats an order with it, then that line shows as unavailable and is left out.
  • Given the network drops after the owner taps Confirm, when the app retries, then exactly one order is created.

The first tells the designer what the repeat screen must show. The second tells you the data model needs to know whether an item is still sold. The third is a hard rule for the API and the app on patchy mobile data, and it will become a test. Good acceptance checks pick out the edge cases before they become bugs. User stories and acceptance criteria shows how to find more of them on purpose.

Next, write down the : the belief that, if it is false, makes the whole app pointless. For a reorder app it might be "owners will trust a repeat order without calling their rep to check it". Say how you will test it cheaply before building, for example with a paper version of the flow and three shop owners. Testing ideas cheaply has four ways to do this, and the next lesson, Screens and flows, does it for this app.

Finally, list the open questions, each with an owner and a due date. "Does a repeated order use today's prices or the old ones? Owner: product manager, due 7 November." A question with an owner gets answered. A question without one becomes a guess in the code, and someone finds it in production.

Keep the whole thing to one page, roughly 400 to 800 words. Put it in your repository as docs/spec.md, next to the code, so it changes through pull requests and keeps its history (Pull requests and code review). When a decision changes the spec, change the spec in the same pull request as the code. A spec that drifts away from the app is worse than none, because people trust it.

In the spec Where it is used Problem, users shapes Screens, flow app-02 Smallest version sizes Tables, API, app app-03, app-04 Acceptance checks become Automated tests app-05 Goals, guardrail score Launch review app-07 Non-goals block Never built weeks saved Edit it with the code
One page feeds the whole project. The problem and users shape the screens, the smallest version decides what tables, endpoints and screens you build, the acceptance checks turn into tests, and the goals and guardrail are what the launch review scores. Non-goals feed nothing, and that is their job: they block work that would cost weeks.

Build it

Write the one-page spec for the reorder app, keep it in the project's repository, and add a small Node.js script that checks the page has every part. You need Git and Node.js 18 or newer (see Node.js and npm).

  1. Start the project repository

    The spec is the first file of the project you build through this course. Create the folder, start Git, and make a docs folder for the spec and a scripts folder for the checker.

    Terminal
    mkdir reorder-app
    cd reorder-app
    git init
    mkdir docs scripts
  2. Work out the numbers before you write a goal

    Goals come from arithmetic on the data you have. Write it out once, so anyone can check it. These are the reorder app's numbers, all approximate:

    Output
    Partner orders a week                    about 4,000
      placed in the Partner app today        about 62%   (company target 75%)
      placed by phone, to about 40 reps      about 1,500 (about 37%)
    Phone orders corrected after delivery    1 in 12  -> about 125 a week
    
    Pilot: 20 shops that phone in at least 1 order a week, for 4 weeks
      orders expected                        20 x 4 = about 80
      goal: 40% of them in the reorder app   about 32 orders
      guardrail: corrections 1 in 12 or better -> at most about 7 of 80
    
    Appetite: 3 weeks for 1 developer

    The pilot goal is small on purpose. Twenty shops cannot move the company's 62% much, but 32 repeat orders out of 80 will tell you clearly whether owners use the app instead of the phone.

  3. Write the first half: problem, users, goals, non-goals

    Save this as docs/spec.md. Each section is a ## heading, and every goal, non-goal and question is a line starting with - , so the script in step 5 can read it.

    Markdown
    # Reorder app for partner shops: one-page spec
    Owner: Imran (product). Builder: you. Status: draft 1, 3 November.
    
    ## Problem
    Partner shops reorder nearly the same items every week, yet about 1,500 of
    the roughly 4,000 partner orders a week still go by phone to about 40 sales
    reps. About 1 phone order in 12 is corrected after delivery: roughly 125 a week.
    
    Evidence: 8 weeks of order data; calls with 5 shop owners.
    "I order the same things every Monday. Typing it all again takes too long."
    (Ravi, corner shop owner)
    
    ## Users
    - Primary: shop owners like Ravi, ordering after closing time, on a cheap
      Android phone and patchy mobile data
    - Also affected: sales reps (fewer calls) and DC pickers (same orders, new source)
    - Decides: Imran. Builds the main Partner app later: Lagoon Digital
    
    ## Goals
    - Pilot shops place 40% of their orders in the reorder app: baseline 0%, target 40%, by the end of week 4
    - Guardrail: corrections after delivery, baseline 1 in 12, target no worse, by the end of week 4
    
    ## Non-goals
    - No payments in the app, because invoices stay on today's process
    - No search or browsing of new products, because repeats are the problem we saw
    - No ordering while offline, because a queued order can be sent twice
  4. Write the second half: smallest version, checks, risks, questions

    Add the rest to the same file. Five items in the smallest version, each step of the journey in its most basic form. The Later list keeps every cut idea visible.

    Markdown
    ## Smallest useful version
    - Sign in as a pilot shop
    - See the last 5 orders, newest first
    - Repeat one order: change quantities, remove lines, confirm
    - See each order's status, from placed to delivered
    - A weekly summary: number of orders and total spent
    
    ## Acceptance checks
    - Given Ravi's last order had 18 lines, when he taps Repeat,
      then a draft opens with the same 18 lines and quantities
    - Given an item is no longer sold, when he repeats an order with it,
      then that line shows as unavailable and is left out
    - Given the network drops after he taps Confirm, when the app retries,
      then exactly one order is created
    
    ## Risks
    - Riskiest assumption: owners trust a repeat without calling their rep.
      Test it with a paper flow and 3 shops before building
    
    ## Open questions
    - Does a repeat use today's prices or the old ones? Owner: Imran, due 7 November
    - Can two people sign in for one shop? Owner: Imran, due 10 November
    
    ## Later
    - Suggested items, promotions, push notifications, drafts saved offline
  5. Add a script that checks the spec

    A spec gets weaker as people edit it: a goal loses its date, a non-goal loses its reason. This script catches that. It uses only Node's built-in fs module, so there is nothing to install. Save it as scripts/check-spec.mjs.

    JavaScript
    // Run it with: node scripts/check-spec.mjs docs/spec.md
    import { readFileSync } from 'node:fs';
    
    const file = process.argv[2] ?? 'docs/spec.md';
    const text = readFileSync(file, 'utf8');
    const problems = [];
    
    // 1. Every required section is there as a "## " heading
    const required = ['Problem', 'Users', 'Goals', 'Non-goals', 'Smallest useful version',
      'Acceptance checks', 'Risks', 'Open questions'];
    const headings = [...text.matchAll(/^## (.+)$/gm)].map((m) => m[1].trim());
    for (const name of required) {
      if (!headings.some((h) => h.startsWith(name))) problems.push(`missing section: ${name}`);
    }
    
    // 2. The "- " lines of one section, up to the next heading
    function items(name) {
      const lines = text.split('\n');
      const start = lines.findIndex((l) => l.startsWith(`## ${name}`));
      if (start === -1) return [];
      const rest = lines.slice(start + 1);
      const end = rest.findIndex((l) => l.startsWith('## '));
      return (end === -1 ? rest : rest.slice(0, end)).filter((l) => l.startsWith('- '));
    }
    
    // 3. Goals need numbers, non-goals a reason, questions an owner
    for (const g of items('Goals')) {
      if (!/baseline/i.test(g) || !/target/i.test(g) || !/\bby\b/i.test(g)) problems.push(`goal needs baseline, target and date: ${g}`);
    }
    for (const n of items('Non-goals')) {
      if (!/because/i.test(n)) problems.push(`non-goal without a reason: ${n}`);
    }
    for (const q of items('Open questions')) {
      if (!/owner:/i.test(q)) problems.push(`question without an owner: ${q}`);
    }
    if (items('Smallest useful version').length > 7) problems.push('smallest version has more than 7 items');
    
    // 4. One page is roughly 800 words at most
    const words = text.split(/\s+/).filter(Boolean).length;
    if (words > 800) problems.push(`spec is ${words} words; aim for 800 or fewer`);
    
    console.log(problems.length ? problems.join('\n') : `OK: ${words} words, every section present`);
    process.exitCode = problems.length ? 1 : 0;
  6. Run it, break it, and commit

    Run the check on the full spec. Then delete the reason from the payments non-goal and the owner from the second question, and run it again to see it fail. A non-zero exit code means you can run the same script in CI later (Continuous delivery).

    Terminal
    node scripts/check-spec.mjs docs/spec.md
    Output
    OK: 407 words, every section present
    Output
    non-goal without a reason: - No payments in the app
    question without an owner: - Can two people sign in for one shop? due 10 November

    Put the reason and the owner back, then commit the spec and the script together:

    Terminal
    git add docs/spec.md scripts/check-spec.mjs
    git commit -m "docs: one-page spec for the reorder app"

    The script checks shape, not judgement. It cannot tell a good goal from a silly one with the right words in it. That part is your job, and the job of the person who reviews the spec with you.

Bring it to your team

Before anyone builds, review the page together with these questions.

  • Who exactly is the primary user, and what did we see or hear from at least five of them?
  • If we hit the goal, what number changes, from what, to what, by when, and where do we read it?
  • What must not get worse while we chase it?
  • Which features will people expect that we are not building, and have we told them why?
  • Can a user finish the whole job with the smallest version, and does it fit the time we agreed?
  • Which open question blocks the most work, and who answers it by when?

Red flags

  • A problem statement that names the app ("shops lack a reorder app").
  • Goals with no baseline, or goals that are a ship date.
  • No non-goals, or non-goals like "it will not be slow".
  • A first version with more than about seven items, or one that cannot be used end to end.
  • A spec that lives in someone's chat messages and no longer matches the app.

Practice

Find the gaps in a spec

Write specGaps(spec), a function that reviews a spec stored as an object and returns a list of the gaps it finds. The spec looks like this: { problem, evidence: [...], goals: [{ metric, baseline, target, by }], nonGoals: [{ item, because }], now: [...], openQuestions: [{ question, owner }] }, and any field may be missing. Return these strings, in this order, for each rule that fails:

  • 'no problem statement': problem is missing or only spaces
  • 'no evidence': evidence is missing or empty
  • 'goal without numbers': there are no goals, or a goal has no baseline, target or by (a baseline of 0 is a real number)
  • 'non-goal without a reason': there are no non-goals, or one has no because
  • 'no smallest version' when now is missing or empty, or 'too big' when it has more than 7 items
  • 'question without an owner': an open question has no owner (no questions at all is fine)
JavaScript exerciseRuns in your browser with tests
function specGaps(spec) {
  const gaps = [];
  if (!spec.problem) gaps.push('no problem statement');
  // add the other rules, in the order listed above
  return gaps;
}
Ctrl + Enter runs
Show a solution
JavaScript
function specGaps(spec) {
  const gaps = [];
  const goals = spec.goals ?? [];
  const nonGoals = spec.nonGoals ?? [];
  const now = spec.now ?? [];
  const questions = spec.openQuestions ?? [];
  if (!spec.problem || !spec.problem.trim()) gaps.push('no problem statement');
  if ((spec.evidence ?? []).length === 0) gaps.push('no evidence');
  // == null catches undefined and null but lets 0 through
  if (goals.length === 0 || goals.some((g) => g.baseline == null || g.target == null || !g.by)) {
    gaps.push('goal without numbers');
  }
  if (nonGoals.length === 0 || nonGoals.some((n) => !n.because)) gaps.push('non-goal without a reason');
  if (now.length === 0) gaps.push('no smallest version');
  else if (now.length > 7) gaps.push('too big');
  if (questions.some((q) => !q.owner)) gaps.push('question without an owner');
  return gaps;
}
Pass the exercise to finish this task.

Cut a wish list to the smallest useful version

Imran has collected ten ideas for the reorder app: sign in; see last orders; repeat an order with changes; order status; weekly summary; pay invoices in the app; AI-suggested items; chat with the sales rep; promotions on the home screen; save a draft order while offline. The appetite is three weeks for one developer. Sort the ten into Now, Later and Never in this version, give a one-line reason for every item outside Now, and write one goal and one guardrail with a baseline, a target and a date.

  • Now covers every step a shop owner needs to repeat an order end to end, and nothing more than about five items
  • Payments are a non-goal or Later, with a reason (they need finance's process, or they are a separate problem)
  • Offline drafts are handled with care: the reason mentions the risk of sending an order twice or the extra work of syncing
  • Every item outside Now has its own reason, not one reason for all of them
  • The goal is about the pilot group, with a metric, a baseline, a target and a date; the guardrail protects delivery accuracy or orders sent twice
Show a model answer

Now: sign in, last orders, repeat with changes, order status, weekly summary. Together they let an owner repeat an order and follow it, and they fit three weeks if each is basic.

Later: AI-suggested items (we need weeks of repeat data before suggestions can be any good); chat with the rep (owners can still phone, and chat needs someone to answer it); promotions (they change what people order, which would blur what the pilot measures).

Never in this version: paying invoices in the app, because invoices stay on today's process and payments need finance's approval; offline drafts, because an order queued on the phone can be sent twice and syncing is a project of its own (the app must still survive a slow network).

Goal: pilot shops place 40% of their orders in the reorder app by the end of week 4, from 0% today, counted in the order table. Guardrail: corrections after delivery stay at 1 in 12 or better over the same four weeks.

Check yourself

A friend wants to build a booking app for her cousin's hair salon. Her spec opens with "The salon needs a modern booking app." What should she write instead?

Which of these is a useful non-goal for the reorder app's first version?

Halfway through the three-week appetite, the builder sees the order-status screen will not be done in time. What fits the method in this lesson?

Flashcards

Open my review

Key takeaways

  • Start from a problem with a named user and evidence; if the statement only makes sense with your app in it, you wrote a solution.
  • Goals need a metric, a baseline, a target and a date that a small pilot can move; add one guardrail.
  • Non-goals with reasons stop stakeholders from waiting and stop you from building.
  • Set the time first, then build a thin slice: a basic version of every step, so a user can do the whole job.
  • Keep the one page in the repository with acceptance checks and open questions, and change it in the same pull request as the code.

Sources

Episode transcriptOne page before the first line of code · about 13 minutes · tap any line to play from there
  1. NadiaImran, you sent me a message last night with one line in it. Read it out for the listeners.
  2. ImranAn app where partner shops reorder, pay, get AI suggestions and chat with their sales rep. I was quite proud of it.
  3. NadiaIt's a good idea. It's also about four different apps. Today we turn that one line into one page: who it's for, what problem it solves, how we'll know it worked, what it won't do, and the smallest version worth building first.
  4. ImranAnd this is the first stage of the whole course project, right? The reorder app.
  5. NadiaYes. Every later lesson uses this page. The screens, the tables, the tests and the launch review all come out of it.
  6. NadiaStart with a picture. Someone opens a food stall near a busy bus station. She could plan twenty dishes, card payments, delivery and a loyalty card.
  7. ImranOr she could start small.
  8. NadiaShe writes one card. Who eats here? Office workers with twenty minutes for lunch. How will she know it works? Eighty plates sold by two in the afternoon on most days. What won't she do yet? No delivery and no card machine, because she can't afford either until she knows people come back.
  9. ImranAnd the menu?
  10. NadiaOne good rice dish, one drink, and a queue that moves. Small, but complete. A customer arrives hungry and leaves fed. That card is a one-page spec, written for a food stall.
  11. ImranFine. So where does my one line go wrong? It sounds like a plan to me.
  12. NadiaIt's a solution. It says what to build, and it hides what's going wrong today, for whom, and how we know. If we build it straight away, we can never say later whether it helped, because nobody wrote down what helped means.
  13. ImranSo the page starts with the problem.
  14. NadiaA problem statement in four parts. Who has the problem, named by role. What they're trying to do, in their words. What goes wrong today. And how we know, with at least one number and one quote.
  15. ImranI have the numbers. About four thousand partner orders a week. About fifteen hundred of them still come in by phone, to roughly forty sales reps. And about one phone order in twelve is corrected after delivery.
  16. NadiaThat's roughly a hundred and twenty-five corrections a week. And the quote?
  17. ImranRavi. He told me he phones in almost the same twenty items every Monday, and typing it all again takes too long.
  18. NadiaNow there's a test I like. Read your problem statement and ask whether a different solution could fix it. A printed order form, or a saved order the sales rep keeps for each shop.
  19. ImranThey could, partly. Does that mean my app is a bad idea?
  20. NadiaIt means you described a real problem, and your app is one of several fixes. If the statement only works with your app inside it, like shops lack a reorder app, then you wrote the solution twice.
  21. ImranThen the users. That's easy. Shop owners.
  22. NadiaThe primary user, yes. The person who actually taps through the app. But write their context too. Ravi orders after closing time, on a cheap Android phone, on patchy mobile data.
  23. ImranWhy does that matter so early?
  24. NadiaBecause it shapes your screens, your timeouts and your tests far more than an age range would. And list who else is touched. Sales reps get fewer calls. The pickers at the distribution centre get the same orders from a new source. You decide. And Lagoon Digital rebuilds it in the main Partner app later.
  25. ImranGoals next. My company target is to move partner orders in the app from sixty-two percent to seventy-five percent.
  26. NadiaThat's the right reason for the project. It's the wrong goal for a pilot. How many shops are in the pilot?
  27. ImranTwenty, for four weeks.
  28. NadiaTwenty shops out of about eighteen hundred. They'll barely move the company number, so after four weeks you'd learn nothing. Pick a number about the pilot group itself.
  29. ImranSo, pilot shops place forty percent of their orders in the reorder app by the end of week four, starting from zero.
  30. NadiaGood. That has the five parts a goal needs. A metric, a baseline, a target, a date, and where you read it. In this case, the order table.
  31. ImranI almost said the goal was to ship by week four.
  32. NadiaThat's a delivery date. An output. You can ship on time and nobody uses it. Now add a guardrail, a number that must not get worse while you chase the goal.
  33. ImranCorrections after delivery. More app orders that arrive wrong would be a failure.
  34. NadiaExactly. Corrections stay at one in twelve or better. That protects the shop owner and the pickers at the other end of your app.
  35. ImranAnd then non-goals. I'll admit, I've always found those a bit silly. The app will not crash, that kind of thing.
  36. NadiaThat one is silly, because nobody planned a crashing app. A real non-goal is something a reasonable person would expect, which you've decided not to do yet, with the reason written next to it.
  37. ImranLike payments. Shops will ask whether they can pay invoices in the app.
  38. NadiaRight. No payments in the app, because invoices stay on today's process. Now nobody waits for it, and nobody builds it on a quiet afternoon. And because the reason is written down, you can reopen it when the reason changes.
  39. ImranWhat about offline ordering? Shops are on patchy data. Surely that's a must.
  40. NadiaIt's tempting. But an order queued on the phone can be sent twice when the signal comes back, and syncing is a project of its own. So the first version needs a connection to confirm. It must still survive a slow network, which we'll handle when we build the app.
  41. ImranOkay. Now my list. I had ten features. Which ones survive?
  42. NadiaBefore you pick, set the time. How much is this problem worth?
  43. ImranThree weeks, one developer.
  44. NadiaThat's an appetite. It comes from Basecamp's Shape Up method. An estimate asks how long the features take. An appetite fixes the time, and the scope bends to fit it.
  45. ImranSo I don't ask how long ten features take. I ask what fits in three weeks.
  46. NadiaYes. Then write the user's journey as steps. Sign in, see last orders, repeat one with changes, see its status, see a weekly summary. Every step must exist, or the job can't be done. And for each step, pick the cheapest version that still works.
  47. NadiaIf you can see your screen, the first diagram shows two ways to spend the same three weeks. On top, two steps are built and polished, and the other three aren't started. Nobody can place an order. Below, every step is basic, and a shop owner can do the whole job.
  48. ImranSo the second one is the thin slice.
  49. NadiaA thin vertical slice. A basic version of every step, built through the screen, the API and the database. People often call it a minimum viable product. The lesson says smallest useful version, because useful is the part people forget.
  50. ImranAnd the ideas I cut, the AI suggestions, the chat, the promotions?
  51. NadiaThey go in a Later list, each with its own reason. Suggestions need weeks of repeat data first. Promotions would change what people order and blur what the pilot measures. Writing cut ideas down makes cutting easier, because nothing is lost.
  52. ImranSo, putting it together for Mangrove. Fifteen hundred phone orders a week, a pilot of twenty shops, a goal of forty percent of their orders in the app by week four, a guardrail on corrections, three weeks, and five items.
  53. NadiaThat's the example in the lesson. And the next step is testing the flow on paper with three shops, before anyone writes code.
  54. ImranHow do I know when each of the five items is done?
  55. NadiaAcceptance checks, written as given, when, then. Given Ravi's last order had eighteen lines, when he taps repeat, then a draft opens with the same eighteen lines and quantities.
  56. ImranAnd edge cases?
  57. NadiaThat's where they earn their keep. Given an item is no longer sold, the line shows as unavailable and is left out. Given the network drops after he taps confirm, when the app retries, exactly one order is created.
  58. ImranThat last one sounds like a rule for the API, not for me.
  59. NadiaIt's for everyone. The designer learns what the screen must show. The data model learns it must know whether an item is still sold. And the API learns a retry must never double an order. Later, each check becomes a test.
  60. NadiaThe second diagram shows that. On the left, the spec's sections. On the right, where each one is used. Problem and users shape the screens. The smallest version sizes the tables and the API. Acceptance checks become tests. Goals are what the launch review scores.
  61. ImranAnd the non-goals point at a box that says never built.
  62. NadiaTheir arrow blocks work. That's their whole job. Two more parts and the page is done. The riskiest assumption, and the open questions.
  63. ImranMy riskiest assumption is that owners trust a repeat order without calling their rep to check it.
  64. NadiaThen test that cheaply before building. A paper flow and three shop owners. And every open question gets an owner and a due date. Does a repeat use today's prices or the old ones? Owner, you. Due the seventh of November.
  65. ImranAnd if a question has no owner?
  66. NadiaIt becomes a guess in the code, and someone finds it in production.
  67. NadiaIn the Build it section, you make the page real. You start the project repository, work out the pilot numbers in plain text, write the spec as a markdown file in a docs folder, and add a short Node script that checks it.
  68. ImranWhat does the script check?
  69. NadiaThat every section is there. That each goal says baseline, target and by. That each non-goal says because. That each open question has an owner. That the smallest version has seven items or fewer, and the page stays under about eight hundred words.
  70. ImranSo it checks shape, not whether my goal is any good.
  71. NadiaRight. Judgement is still yours. But it catches the slow decay, when a goal loses its date in an edit. And because it exits with an error, you can run it in CI later. Then you commit the spec next to the code, and change it in the same pull request as the code.
  72. ImranFor my next review with the team, I'd ask three things. If we hit the goal, what number changes, from what, to what, by when? Which features will people expect that we aren't building, and have we told them why? And can a user finish the whole job with the smallest version?
  73. NadiaGood list. Now a question for you, and take a second. Halfway through the three weeks, the status screen won't be done in time. What do you do?
  74. ImranMove the date back?
  75. NadiaThat turns the appetite back into an estimate. Keep the date and make the step simpler. A plain line of text per order, instead of a tracking screen. The step stays, so the slice still works end to end.
  76. ImranSo my three takeaways. One, start from a problem with evidence, and if it only makes sense with my app in it, I wrote a solution. Two, a goal has a baseline, a target and a date that the pilot can move, plus a guardrail. Three, set the time first, then build a basic version of every step.
  77. NadiaAnd one addition. Non-goals with reasons. They protect your three weeks more than any feature you add.
  78. ImranNext time, we sketch the reorder flow on paper and put it in front of a real shop owner before we build anything.
Finished reading?Mark it complete to fill in its stop on your course line.

Use it at work

PRD for a new feature

Problem with numbers, users, goals and non-goals, measurable metrics with a guardrail, user stories with acceptance criteria, scope, risks and launch.

Open in the Product & BA Lab
Next stopScreens and flows
Was this lesson helpful?
Questions and discussion

Loading the discussion…