October 8, 2025 at 15:16
There’s so much I want to share with you: setting up network-wide ad blocking, Cloudflare Tunnels, custom 3D prints, my Halloween costume, self-hosting a Google Photos replacement, task organization, smart goggles, self-hosted calendars and contacts, and so much more.
But today’s project is top of mind and pretty exciting - making weekly meal preparation awesome!
Up until last week, I was getting meal deliveries from Factor75. It was the perfect service for a while because it:
Then the problems started. Over the last three weeks, I had two failed deliveries. One box never arrived, and the next one was delivered down the street. By the time I managed to reach it, it was soaking wet and questionable.
No matter how convenient the meals are, if I can’t rely on them for the week’s food planning, it’s not worth using.
As usual, I decided to address the issue my own way.
I built a small web app with a Python backend that reads from two JSON files:
This modular design allows for overlap and re-use of ingredients. For example, selecting both Chicken Pot Pie and Thai Green Chicken Curry automatically adds two portions of chicken plus all the necessary ingredients for each dish.
components.json
{"id":"cmp_mushrooms","name":"Cremini Mushrooms","category":"fresh_quick","storeSection":"Produce","portionName":"cup, sliced","portionSize":1,"caloriesPerPortion":15,"proteinPerPortion":2,"isBatchable":false,"prepNotes":"Roast or sauté."},
{"id":"cmp_cavatappi","name":"Gluten-Free Cavatappi","category":"on_hand","storeSection":"Bread & Grains","portionName":"cup cooked","portionSize":1,"caloriesPerPortion":200,"proteinPerPortion":6,"isBatchable":false,"prepNotes":"Boil to al dente."},
{"id":"cmp_almond_milk","name":"Almond Milk (unsweetened)","category":"on_hand","storeSection":"Dairy & Eggs","portionName":"cup","portionSize":1,"caloriesPerPortion":30,"proteinPerPortion":1,"isBatchable":false,"prepNotes":"Use in mash/sauces."},
{"id":"cmp_black_beans","name":"Black Beans (canned)","category":"on_hand","storeSection":"Snacks/Pantry","portionName":"1/2 cup","portionSize":0.5,"caloriesPerPortion":114,"proteinPerPortion":7,"isBatchable":false,"prepNotes":"Rinse for bowls."},
meals.json
{
"id": "meal_cavatappi_ragu",
"name": "Cavatappi & Italian-Style Pork Ragù",
"category": "main",
"ingredients": [
{ "componentId": "cmp_pork_ragu", "quantity": "1 portion" },
{ "componentId": "cmp_gf_pasta", "quantity": "1 portion" },
{ "componentId": "cmp_olive_oil", "quantity": "1 tsp" }
],
"prep": "Cook pasta, toss with ragù. Freeze sauce separately if batching.",
"nutrition": { "calories": 455, "protein": 32 },
"tips": ["Add olive oil or shredded cheese for more calories."]
},
As you can see by the examples above, both ingredients and meals are easily updated and managed.
At the top of the grocery section, there’s a Copy Grocery List button. This button will take your list, format everything in Markdown, and sort ingredients by store section. This allows for easy pasting directly into my new self-hosted notes app (which is now added to my list of things to talk about). Otherwise, local storage will maintain your list while you shop.
AI was heavily involved in building this. Each model has its quirks and specialties, but together they can make for fantastic coworkers. They feel like having a Mr. Meeseeks button at my side.
I’ve been coding and scripting basic stuff for so long that much of it feels like tedium. Now, I can have a bot pore through files and fix problems while I focus on higher-level logic and design. They can behave like a project manager or a UI / UX expert. OpenAI Codex was used during development, Claude Sonnet cleaned and polished the UI, and Google’s Gemini struggled to give me a list of names for the project. It’s okay buddy. You’re important too.
It honestly feels like working with a large team as my productivity has shot through the roof. What an incredible era for our kids to grow up in!
The final recipes and nutrition section still needs work. It’ll eventually include step-by-step instructions, substitution tips, and photos. I’ll do that in a later sprint.
Factor75 won’t be delivering to our house anymore, so next week is our first live-fire exercise. I’ll report back once I see how it performs with my weekly workflow.
Cross your fingers.
Questions or comments?