Skip to content
All example projects

Web app

Recipe inbox

Collect recipes and boil them down to the essentials

A web app that turns a pasted recipe into a plain ingredient and step list — without the story around it.

Worked teaching examples: these three projects were written for the course along the documented seven-day rules. They are not real user projects, there is no running app, no live link and no store listing. The evidence here is the decisions, not a screenshot.

What it was built for

Recipes online sit between long preambles, ads and photos. Anyone standing in the kitchen wants ingredients and steps. The app takes a pasted text or a link and files the essentials as a card.

The core loop in four steps

  1. 1Open — your own collection is there
  2. 2Drop in a recipe — paste text or give a link
  3. 3Check the result — ingredients and steps, correctable
  4. 4Save and carry on — the card sits in the collection

Deliberately left out

Shrinking the scope is the real work of day 1. These points would have made the project bigger without making the core loop better.

  • No shopping list — the most obvious next step, but a flow of its own with its own states. It is on the V1.1 list.
  • No quantity scaling by servings — it sounds trivial and is not, with real recipes ("a pinch", "a bunch").
  • No sharing and no public collections — that requires permissions, visibilities and an answer to other people's copyright.
  • No photo import via camera — the text recognition would be a second paid path alongside the one that already exists.

Release goal

Publicly reachable web app with a signed-in area for your own collection.

The seven build days

For each day you see separately what was visible afterwards and what decision sat behind it. Where something did not work at first, that is here too.

  1. 1Day 1 — Your scope is set

    What was built
    A spec with the core loop, four non-goals and the early commitment that exactly one paid path is allowed.
    Why this way
    Boiling down the recipe text is handled by a paid service. This dependency was deliberately allowed on day 1 and confined to exactly one place — any further one would have meant a second cost path, a second limit and a second failure case.
  2. 2Day 2 — A real build runs

    What was built
    A running project with sign-in, two views and a server-side route behind which the paid service sits.
    Why this way
    The service key sat on the server from the first line, never in the browser. A key in the browser is not a mistake you repair later — it is public from the first deploy.
  3. 3Day 3 — Your core loop works

    What was built
    The complete flow from pasted text to saved card, with a correctable intermediate result.
    Why this way
    The result is editable before it is saved. An automatic process sometimes gets it wrong; without a correction step the error lands permanently in the collection and the user loses trust in every card.
  4. 4Day 4 — Your app survives bad days too

    What was built
    Empty collection with a way in, unusable input with an explanation, service unreachable with a retry, slow response with an honest waiting state.
    Why this way
    "Service unreachable" got its own handling separate from "text unusable". Showing both as one error would have blamed the user for an outage they did not cause.
  5. 5Day 5 — Operations, legal and cost limits are set

    What was built
    Legal texts, support route and a server-side cost limit per user and day, plus a reachable kill switch for the whole import.
    Why this way
    The limit is checked by the server before every call to the service, not by the browser. A sign-in says who someone is, not how much they may consume — the order is request, check, reserve budget, start service, record usage.
    What did not work at first
    The first version counted usage only after the service replied. Two imports sent in quick succession therefore both went through even though the daily limit was reached after the first. Budget has been reserved beforehand ever since.
  6. 6Day 6 — A real release candidate

    What was built
    A publishable state, tested in two browsers and on a real phone, with a test account for reviewers.
    Why this way
    The test account already holds three example cards. An empty account forces every reviewer to use the import first — and therefore precisely the part that depends on an outside service.
  7. 7Day 7 — Your decision is documented

    What was built
    A record of all release gates with evidence, plus a V1.1 list headed by the shopping list.
    Why this way
    It shipped. The deciding factor was that the single paid path has a checked limit and a reachable kill switch — without both, the app would not have gone out despite a working core loop.

Take it and remix it

The remix takes the idea, core loop, non-goals and release goal as your starting point — not the solution. The seven build days stay identical; you skip no step and no check.

Prompt for your AI tool

If you would rather start right away instead of going through the path: this prompt describes the project completely enough for an AI tool to begin.

I am building a small web app: Recipe inbox — collect recipes and boil them down to ingredients and steps.

Core loop in four steps:
1. Open — my own collection is there
2. Drop in a recipe — paste text or give a link
3. Check the result — ingredients and steps, correctable
4. Save and carry on

Explicitly NOT in version 1: shopping list, quantity scaling by servings, sharing and public collections, photo import via camera.

Release goal: publicly reachable web app with sign-in. Exactly ONE paid path is allowed (boiling down the recipe text) — with a server-side check before every call, a daily limit and a kill switch.

Help me get started:
1. Ask me about anything you need to know for the first step.
2. Propose the smallest data structure that carries this core loop.
3. Describe the server-side chain request → check → reserve budget → start service → record usage for my case.

Do not change the scope without asking me.