Build Pestle

YESreplaces $2.99/mosaves $35.88/yrback to the verdict

0%0 of 13 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A household recipe box whose hard problems are a cooking mode that keeps working when the browser throttles it, a shopping list two people can tick offline without losing an item, and keeping the whole box portable enough to leave.

estimated effort one sittingthe files for this build are in the project pack

RuntimeNext.js with TypeScript, installed to the home screen as a local-first web appStorageSQLite on a small server for the household, with a local copy in the browserTimersStored end timestamps, remaining time computed from the clock on every renderList syncPer item state with last-writer-wins on the item, never on the listPortabilityWhole-box export as JSON plus images, importable into an empty instance

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the household server and the build.

    Get it nodejs.org or your version manager. open ↗

    Verify node --version prints v22 or higher

  2. have readyfree

    Why Cooking mode, the wake lock and the timer reconciliation can only be judged on the device that will be on a worktop with wet hands.

    Get it Open the app on the phone over the local network and add it to the home screen.

    Verify A timer started and backgrounded reports correctly on return

  3. have readyfree on hardware you own, or a few pounds a month

    Why The household needs one place to agree with, and the wake lock and installability both want a secure origin.

    Get it Any small machine or home server with a local certificate, or a cheap instance with a real one.

    Verify Two devices reach the same household over a valid certificate

  4. have readyfree

    Why The list merge is the part most likely to lose data and it cannot be tested with one device.

    Get it Any second phone, tablet or browser profile that can be put into aeroplane mode.

    Verify Both devices edit offline and reconcile without loss

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- recipes(id, title, source_url, source_name, servings, notes, created_by, updated_at)
- ingredients(recipe_id, position, quantity, unit, item, note) · structured rather than a free text line, because the list depends on it
- steps(recipe_id, position, text, timer_seconds) · a step may carry a suggested duration that becomes a timer
- cooks(id, recipe_id, started_at, current_step, finished_at) · one run through a recipe, so you can leave and come back
- timers(id, cook_id, label, ends_at, acknowledged_at, cancelled_at) · an end time, never a remaining count
- list_items(id, household_id, text, quantity, unit, source_recipe_id, state, state_changed_at, changed_by) · state is needed, in trolley or done
- members(id, household_id, name, joined_at) and households(id, name, invite_code, created_at)

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATABASE_PATHrequired./data/household.dbRecipes, lists, cooks and timers. Back this up; recipes are typed once.
IMAGE_DIRrequired./data/imagesRecipe photos. Included in every export as files.
PUBLIC_BASE_URLrequiredhttps://kitchen.localUsed in invite links and needed for a secure origin.
INVITE_CODE_TTL_HOURSrequired48How long a household invite code stays valid.
MAX_IMAGE_BYTESrequired2097152Per photo, after the device resizes it.
BACKUP_DIRrequired./backupsScheduled archives of the database and images together.

The build, in order

  1. A box that opens in a kitchen

    Recipes are structured, editable and readable on a phone with no signal.

    1. Everything downstream depends on quantity and unit existing.

      Files src/db/schema.tssrc/lib/ingredients.ts

    2. A stale copy you know about is fine; one you do not is not.

      Files src/lib/offline.ts

    3. Doubling a cake does not double the bake.

      Files src/lib/scale.tstests/scale.test.ts

    done when · tick each as it passes
    watch out
    • Storing ingredients as one text line per row is quick and makes every later feature impossible, because a shopping list cannot merge two hundred grams of butter with a knob of butter when neither has a quantity or a unit. Store quantity, unit and item separately from the start and accept a fiddlier entry form.
  2. Cooking mode, and clocks you can trust

    The screen stays on when it can, and every timer is correct when you come back to it.

    1. The clock is the only thing that keeps running.

      Files src/lib/timers.tstests/timers.test.ts

    2. The lock is dropped when the page goes away and does not come back by itself.

      Files src/lib/wakelock.ts

    3. One honest sentence beats a silent failure over a hot pan.

      Files src/app/cook/page.tsx

    done when · tick each as it passes
    watch out
    • Building the timer as a countdown in a repeating callback means that when the phone locks or the tab goes to the background the callback is throttled or stopped, and the user returns to a timer showing four minutes left that should have rung twenty minutes ago. Store the end time, compute from the clock, and reconcile on every wake.
  3. A list two people can tick at once

    Two members editing the list offline both keep their changes.

    1. This is the difference between a household tool and an argument.

      Files src/lib/list-sync.tstests/list-merge.test.ts

    2. A stale device will otherwise bring the milk back.

      Files src/lib/list.ts

    3. So removing a meal from the plan can remove its items.

      Files src/lib/list.ts

    done when · tick each as it passes
    watch out
    • Syncing the list as one document and taking whichever copy was saved most recently means the person in the shop who ticked off eight things overwrites the person at home who added three, and nobody finds out until dinner. Merge per item on the time its own state changed, and keep deletions as tombstones so a slow device cannot resurrect them.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more home.