Status: Live demoCo-built with partners

Mochi Kitchen

AI recipe finder

Describe a craving or list what's in the fridge, and Mochi finds recipes, merges shopping lists, ranks recipes by what you already own and plans your week. Built with Node, Express and Sequelize locally, and a Hono API on Cloudflare D1 in production — both sharing the same pure logic.

Mochi Kitchen: What shall we cook today? A search box with diet filters and the Mochi cat mascot.
Built with
Node.jsExpressSequelizeJavaScriptHonoCloudflare WorkersCloudflare D1TheMealDB APIGemini API
Type
Personal project
Source
Public on GitHub

What was built

  • Free-text search that tokenises and stems, then detects ingredients, cuisine, diet and calorie limits such as “under 500 calories”. repo docs
  • Shopping lists that merge and de-duplicate ingredients and add units: 500 g + 0.7 kg = 1.2 kg. repo docs
  • Accounts with short-lived JWTs and rotating, hashed refresh tokens with replay detection; Joi validation, rate limits and a CSP. repo docs

My part

  • My Full Stack Development II project: 19 of 23 commits are mine, including the Worker placement fix. A collaborator added a Java microservice and a later theme. commits

Limits and open work

  • Measured cold sign-up used 42 ms CPU — above Workers Free's documented 10 ms limit. It wasn't rejected in practice, but Cloudflare doesn't promise that. repo docs

Decisions worth knowing

  • Move the Worker to the data

    D1 lives in Tokyo and a search makes dozens of small queries, each costing ~250 ms from another continent. Pinning the Worker next to the database took searches from up to 40 s to about 1–4 s.

    repo docs

  • One logic, two runtimes

    NLP, diet rules, grocery merging, scoring and the planner are pure modules shared by the Express app and the Worker, so behaviour is identical.

    repo docs

  • Estimates say they're estimates

    Calories are always shown as “approx.” or “AI estimate”.

    repo docs

A closer look

500 g+ 0.7 kg= 1.2 kg
Figure — merging a shopping listrepo docs The README's own example of unit-aware merging.