Skip to content
AFM Studio
  • Pages

    AFM Studio
  • Work
  • Lab
  • About
  • CV
  • Contact
  • Projects

    AksaraA searchable library for Otorita IKN's knowledge, where the server checks every reader's access across three levels
  • Daily TaqwaTamper-resistant prayer attendance system for ~2,000 OIKN government employees at Masjid Negara IKN
  • Lantara v2A permit engine for Otorita IKN where administrators add new permit types from a screen, without a developer
  • eKiosk IKNTwo control rooms for Nusantara: kiosk content management and live bus tracking with arrival times that grade themselves
  • E-Monev IKNA monitoring platform for Nusantara's 23-year build, tracking every unit's quarterly progress against 24 national KPIs
  • JDIH OIKNOIKN's public legal document portal, with a controlled publishing workflow and AI summaries that never leave the server
  • Jejak PenanamanA check-in app for IKN tree-planting events that proves each participant was on site with a geofenced selfie
  • Dashboard SAKTIA nightly pipeline and dashboard that replaces OIKN's manual budget downloads for all six of its budget units
  • DoseRxA bedside dose calculator for 127 drugs that rounds each dose to tablets and syrups Indonesian pharmacies sell
  • CubiqA speedcubing trainer with competition-grade timing and a solver I wrote for each of the 8 major puzzles
  • ScimotionAn interactive science library of 86 articles, each explained next to animations the reader can control
  • WA Daily Scrum BotA WhatsApp bot that chases missing standup reports for a 14-person team and flags tasks stuck for days

↑ ↓ to move · Enter to open · Esc to close

Gizi Masakan

Nutrition facts for 40 Indonesian dishes, with the recipe behind every number shown so you can correct it

Screenshots
Indonesian dishes with editable recipes
40
nutrients from USDA FoodData Central
29
ingredients mapped to Indonesian names
70
network requests after the page loads
0
On this page

The problem

People in Indonesia who want to know what is in their food mostly use apps built on foreign food databases. Search for nasi padang, gado-gado or soto betawi and you get nothing, or a US dish that looks little like the one on the plate. The apps that do list Indonesian dishes give one confident number with no working. "550 kcal for gado-gado." Whose gado-gado, with how much peanut sauce? Nobody can check that number, so nobody can correct it.

Most of these apps are also calorie trackers. That suits weight loss. Indonesia's bigger nutrition problems are stunting and missing micronutrients, so the useful question is "am I getting enough iron and protein". A calorie budget can also harm people with disordered eating.

What I built

The recipe sits under every number

Each dish page shows its ingredients and their gram weights right below the nutrition figures. You can edit any weight or switch a cooking method, say from fried to boiled, and the totals, contribution bars and adequacy fills update as you type. Two food stalls make gado-gado differently, and that difference is bigger than any precision the app could claim. Showing the recipe lets you fix the number for your own kitchen.

A missing value is always named

The most dangerous thing a nutrition calculator can do is quietly skip an ingredient it has no data for. The total still looks plausible, but it is too low. I made every missing ingredient, nutrient value or cooking factor show up as a named gap, and the total is labelled incomplete. Tests check both directions: an incomplete recipe must name its gap, and a complete one must name none. A cooking-loss adjustment is either applied with its source cited or marked as not applied.

The better data source ships switched off

The better source for Indonesian ingredients is TKPI, the Ministry of Health's food composition table. It is a copyrighted book with all rights reserved, and Indonesia's copyright law only exempts regulations. So I built a TKPI adapter and shipped it disabled, with the legal reason written into the data manifest. The build fails if any source has no licence recorded. If permission ever comes, accuracy improves and nothing else needs to change.

The site is open about its own guesses

All 40 recipes use estimated gram weights, not kitchen-scale readings. Every estimated row is marked "perkiraan" and shown in terracotta. My own notes record that reaching forty guessed dishes was the wrong trade, and that weighing them is the most valuable work left. The household-measure table (centong, mangkuk) ships empty, because a rule in the project forbids entries nobody measured.

Adequacy, never a budget

Nutrient adequacy uses the Indonesian recommended intakes (AKG) from Permenkes 28/2019, by age and sex group. The page shows how much of a day's requirement a dish contributes, with the requirement figure printed beside it. There are no daily totals, no running sums and no food log. A test drops any stray timestamp from the saved-recipe store, so tracking can't creep in.

Result

Gizi Masakan is live and public, in Indonesian first and English second. It covers 40 Indonesian dishes and 70 ingredients, with 29 nutrients each, taken from USDA FoodData Central. The site is fully static and makes no network requests once it has loaded. Tap any total to see which ingredient contributed what, from which database entry, with which cooking factor, and the arithmetic written out. I built it alone in one day of about eight hours in August 2026.

The site says plainly that ingredient values are US-database approximations for Indonesian ingredients, that dish numbers are estimates from a stated recipe, and that it is not medical advice.

Under the hoodTechnical detail for engineers
  • The engine is a pure function, (recipe, portion, ingredientTable, factors) → NutritionTrace: no DOM, no React, no clock, no randomness, no network. Components only render a trace.
  • 282 tests pass across 9 suites: conservation, gaps, retention, determinism, AKG, cooking method, URL state, saved recipes and search.
  • A build-time pipeline downloads the FDC SR Legacy bulk CSV, filters it to the 70-ingredient curated list, projects it to 29 nutrients keyed by FDC nutrient number, and writes a 28.9 KB table.json against a 200 KB budget. Raw CSVs are never committed.
  • Yield and retention factors come from the FAO/INFOODS and USDA tables, cited per operation. The trace states the arithmetic: berat ÷ 100 × nilai per 100 g × faktor retensi.
  • TKPI is excluded under UU 28/2014 Pasal 42. Both adapters emit the same IngredientTable, and nothing downstream branches on provenance.
  • The 13 unmatched ingredients live in unmatched.json and appear as gaps in every trace. Without gula-merah, wedang jahe shows 16 kcal a glass; without kecap-manis, four dishes lose their sugar.
  • Selected nutrient, per-portion toggle, AKG group, edited weights, cooking method and search are all query parameters. Untrusted input from the URL or localStorage is validated with Zod and never coerced.
  • Saved-recipe keys are exactly {id, dishId, nama, beratOverrideG}.
  • Every ink colour clears WCAG AA 4.5:1 on both backgrounds; four hues set by eye failed and were darkened. A third font family kept for tabular numerals was dropped for font-variant-numeric.
  • Four runtime dependencies: Next.js 14.2.15 (output: 'export'), React 18.3.1, React DOM and Zod 3.23.8. Deployed to GitHub Pages by two GitHub Actions workflows, deploy.yml (gated by data:validate) and a scheduled refresh-fdc.yml.
  • About 87 prerendered pages across two locales. About 7,700 lines of TypeScript and 60 commits between 09:21 and 17:35 on 7 August 2026.

Screenshots

Beranda
Masakan
Detail Masakan
Bahan
Metode

Hiring, or building something similar?

I'm open to full-time roles and select freelance work.