A single-file, offline-first app for slowing down at meals: photograph the plate, then rate portion size, run a timer while you eat, when you stopped, and how well you chewed. Everything is tracked locally to build a streak.
![]() |
![]() |
![]() |
![]() |
| Mainpage | Meal timer | Meal data | Pattern overview |
No account, no server, no network calls. The whole app is one HTML file. Your meal photos, ratings, and notes are stored only in your browser's local storage on your own device and are never uploaded anywhere.
| File | Needed for |
|---|---|
index.html |
The app itself. This is the only file required to use it at all. |
manifest.json |
Lets the app be "installed" with a home-screen icon and no browser bar. |
sw.js |
Service worker — caches the app so it opens with no internet connection. |
icon-192.png, icon-512.png |
App icons used by the manifest / installed app / APK. |
If you only want to open the app and use it, you only need index.html.
The other files are only needed for installing it as an app or building the APK.
- Download
index.html. - Double-click it, or drag it into any browser window.
That's it. It runs entirely offline, works the same on desktop or mobile, and nothing is installed. Your data stays wherever your browser stores local site data for that file — if you move or rename the file's location significantly (or clear browser data), you'd lose history, so export a backup from Settings → Export JSON occasionally.
This uses the hosted version (e.g. GitHub Pages), not the raw file, so the manifest and service worker can register.
- Open the hosted URL in Chrome.
- Tap the ⋮ menu → Add to Home screen / Install app.
- It now opens full-screen from a home-screen icon, no address bar, and keeps working offline after the first load.
- Open the hosted URL in Safari (must be Safari — other iOS browsers can't install web apps).
- Tap the Share icon → Add to Home Screen.
- It opens full-screen from the home screen. Safari doesn't use the service worker the same way Chrome does, so keep a connection for the very first load after any update.
This is a plain Android APK — it contains no Google Play services calls, no analytics SDK, and requests no network permission it doesn't need (it makes no network calls at all once installed). That makes it a good fit for de-Googled or sandboxed setups like GrapheneOS, /e/OS, or a stock phone with a work profile / isolated user you don't want online.
- Get
mindful-meals.apk(built via PWABuilder from the hosted site — see repo history / releases, or build it yourself by pointing pwabuilder.com at the hosted URL and using its Google Play packaging option, which outputs a signed/unsigned.apk). - Transfer the
.apkto the device (cable, cloud file, or download directly if the device has any browser access). - Open the file. Android will prompt to allow installs from that source — approve just for this install if you want to keep the "unknown sources" permission narrow.
- Install. No Play Store account, no Google services, and no network connection are required for the app to run — you can leave the device offline permanently and it will work exactly the same.
- Optional hardening for sandboxed installs: deny the app any network permission at the OS level (e.g. GrapheneOS's per-app internet toggle, or a firewall app) — the app never needs it, so blocking it costs you nothing and guarantees no data ever leaves the device even if a future version tried to.
- Stored in IndexedDB (falls back to localStorage, then in-memory) on the device/browser you're using — not synced, not backed up automatically.
- Settings → Export JSON gives you a full backup file; Import a backup restores it. Only ever import a backup file you created yourself.
- Settings → Export CSV gives a spreadsheet-friendly view without photos.
- Settings → Delete everything wipes all local data permanently.
- Meal photos are re-encoded through a canvas before saving, which strips any location/EXIF metadata automatically.
- Nothing in this app phones home. If you're auditing it: search the source
for
fetch,XMLHttpRequest, or<script src=pointing off-device — there are none.
- This web app was written by flowcoding using Claude



