DEV Community

Cover image for Let's Not Be Hangry: An Open-Model App for My Boyfriend, Who Forgets to Eat
Tanya Mott
Tanya Mott

Posted on

Let's Not Be Hangry: An Open-Model App for My Boyfriend, Who Forgets to Eat

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🀝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built

My boyfriend has been staying with me while I recover from ankle surgery. He's been taking care of me, and I noticed he wasn't taking care of himself. He forgets to eat. When he's busy, lunch just doesn't happen. And because it's my kitchen, he's hesitant to help himself to anything.

So I built Let's Not Be Hangry, a tiny app with one job: make eating faster and easier than skipping.

  • "How much time you got?" He taps 1 min, 5 min or 15 min, and Gemma picks something from my kitchen that fits, tells him exactly where it is ("freezer door"), and how to eat it. No-cooking options come first.
  • A "fair game" list. I filled it with everything he's welcome to. If it's on the list, it's his. No asking, no guilt.
  • "Finished it πŸ›’" adds the item to a restock list for me, so "I ate the last yogurt" becomes a helpful heads-up instead of an apology.
  • Meal-time nudges. If nothing's been logged by the end of his lunch or dinner window, he gets a friendly reminder that Gemma writes fresh each time, so it never gets stale.
  • A big "I ate!" button that's always in reach of his thumb.

The rules I gave the model: be warm, short and a little funny. Never mention calories, diets or guilt. Just help him eat something.

What he said when I handed it to him:

  • "It's pretty cool"
  • "It took a bit to figure out but seems self-explanatory"
  • "The colors makes it easy to navigate"
  • "It helped me decide what to eat with the time I had available"
  • "The reminders were helpful"
  • One of the first picks it gave him: String cheese, fridge door. "She'd much rather you be fed than hungry, so go for it!"

Demo

Live app: https://lets-not-be-hangry.onrender.com

app screenshot

Heads-up: it's on Render's free plan, so the first load after it's been idle can take up to a minute.

Code

Let's Not Be Hangry

A tiny app for someone who forgets to eat. Tap how much time you have (1, 5 or 15 min) and Gemma, an open-weight model, picks something from the "fair game" list and says where it is. "I finished it" adds the item to a restock list. Meal-window reminders show up if nothing was logged.

How it's built

  • Angular 22 frontend (signals, zoneless)
  • Node/Express server (server.mjs) that serves the app and forwards /api/chat to Gemma
  • Gemma, two ways
    • LLM_PROVIDER=google: Gemma through Google AI Studio (works anywhere, e.g. on Render)
    • LLM_PROVIDER=ollama: Gemma through local Ollama (nothing leaves your machine)
  • The fair-game list, restock list and log are stored in the browser (localStorage).
  • If the model can't be reached, the app falls back to a built-in "demo mode" pick.

Run locally

Needs Node 22.22.3+ (or Node 24).

npm install
npm run build

Option…

How I Built It

  • Model: Gemma 4 31B, an open-weight model, served through Google AI Studio so it works on his phone anywhere.
  • Local inference: flip one environment variable (LLM_PROVIDER=ollama) and the same app runs Gemma locally through Ollama on my laptop, and nothing leaves the house.
  • Server: a small Node/Express server that serves the app and handles one endpoint, /api/chat. It decides where Gemma runs, keeps the API key out of the browser, and adds a simple rate limit so the public demo can't be abused.
  • Frontend: Angular 22 with signals and the default zoneless setup. It's phone-first, with chunky, playful buttons and a sticky bottom bar. The lists live in the browser's localStorage.
  • Resilience: if Google returns an error, the server retries, and if that model is still down, it automatically switches to another Gemma model my key can use. If no model can be reached, the app falls back to a built-in pick, so it never leaves him empty-handed.

I built this with Claude as my pair programmer. It helped me scaffold the Angular app and the Node server, fix bugs, and work through hosting options. I made the product calls, designed the experience around him, and deployed it.

The trickiest part wasn't the UI. It was the model. The Gemma version I started with wasn't available to my key anymore, and the bigger one sometimes threw server errors. Instead of hardcoding a fix, I had the server ask Google which Gemma models my key can actually use and fall back gracefully. It's a small reminder that open models come in a family, and you can swap between them.

Why Does Open Innovation Matter?

This app knows his routines: when he eats, when he doesn't, what's in our kitchen. That's personal. Building on an open model means I get to decide where that information goes.

  • Swappable: the same app runs on hosted Gemma or on local Gemma with a one-line config change. I'm not locked into one company's API.
  • Private when it matters: in local mode, Gemma runs entirely on my laptop with Ollama, so nothing goes to a server I don't control. A closed API can't offer that.
  • Cheap to keep alive: it runs on a free tier of hosted Gemma, or on a small local Gemma on my laptop. No subscription required.
  • Mine to shape: I can change the prompt, the tone or even the model itself without asking permission.

A closed API would have worked for the demo, but this is the version I'd actually want running in my home.

Prize Categories

  • Best Use of Gemma: Gemma 4 31B picks every meal and writes every nudge, with a local Gemma mode through Ollama.
  • Best Use of Render: the Node server and Angular app run as one Render web service.

Built with love for my favorite forgetful eater. 🍌

Top comments (0)