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.

隐私设置

在你同意后,PostHog EU 会统计哪些页面被打开,并额外录制你的会话:鼠标移动、点击、滚动以及页面呈现的内容会被保存为可回放的重建记录。你输入的文字在发送前会被遮蔽。登录、注册、密码找回、创始人聊天、订阅邮件输入框、你的邮箱显示、你的测验答案以及检查清单的内容完全不会被录制;在登录和注册页面,录制处于暂停状态。网址始终不带查询参数保存。此外还会处理一个随机设备标识以及 IP 地址等技术连接数据。除此之外,还会统计少数严格定义的使用事件:文章被读到什么程度、使用了哪个文章模块、点击了哪个行动号召,以及订阅邮件的结果如何。仅传输固定清单中的取值——不含输入内容,也不含自由文本。 了解更多隐私信息

未经你同意,不会加载任何分析代码,也不会进行录制。你可以随时撤回:撤回会立即停止采集;此前已采集的数据可能已经传出,并会在存储期限后删除。