Skip to content
← All projects

Baseform

Nutrition, training and recovery as a PWA: no server, no account, works offline.

Role
Sole developer, own project
Period
July 2026, ongoing
  • React 18
  • Vite
  • PWA
  • ZXing
  • localStorage
  • SVG
  • Google Health API
  • OAuth 2.0
  • Anthropic Messages API

What it does

Beyond the first paragraph this page is still in German. A full translation is on its way.

Born from my own need: nutrition, training and recovery in one place, without data leaving the device. Barcode and QR scanning against Open Food Facts, a training plan with 26 data-driven exercise animations, Fitbit values via Google Health and an AI coach that works with the remaining daily budget. No server and no account was the starting condition, not the result, which moves the hard questions from authorisation to storage: who owns the state when there is no server to arbitrate? It is the one project I use every day, and the September fixes all came from that use rather than from a test plan.

Aus Eigenbedarf entstanden: Ernährung, Training und Erholung an einem Ort, ohne dass dafür Daten das Gerät verlassen. Barcode- und QR-Scan gegen Open Food Facts, ein Trainingsplan mit 26 datengetriebenen Übungsanimationen, Fitbit-Werte über Google Health und ein KI-Coach, der mit dem verbleibenden Tagesbudget rechnet.

Kein Server und kein Konto war die Ausgangsbedingung, nicht das Ergebnis. Das verschiebt die schwierigen Fragen von der Berechtigung zur Speicherung: Wem gehört der Zustand, wenn es keinen Server gibt, der schlichtet?

Baseform ist das einzige Projekt, das ich selbst täglich benutze, seit Ende Juli als Trainingsprotokoll im Gym. Die Korrekturen vom September stammen alle aus dieser Nutzung, nicht aus einem Testplan.

Numbers

lines of code
~2300 lines of code
data-driven exercise animations
26 data-driven exercise animations
servers, 0 accounts
0 servers, 0 accounts

Screenshots

Heute. Tagesring, Balken für Protein, Fett und Salz, darunter die Mahlzeiten.
Scannen. Treffer live von Open Food Facts, Menge und Mahlzeit wählen.
Training. Animation, Ausführungshinweis, Maschinen-Einstellung, Gewicht pro Satz.
Wochenauswertung. Erledigte Sätze gegen den Plan, als Balken und Heatmap.
Coach. Restbudget, Vorrat als Chips, drei Modi. Der Schlüssel bleibt auf dem Gerät.

Datenverlust bei zwei offenen Fenstern, und was daraus im Schema wurde

Zwei parallel geöffnete Fenster überschrieben sich gegenseitig: Alle Daten lagen als ein JSON-Block unter einem Schlüssel, beide Fenster schrieben ihn komplett zurück, und das Fenster mit dem älteren Stand löschte Tage, die es nie gesehen hatte. Der Fehler hat echte Trainingsdaten gekostet, was ihn zur besten Lektion des Projekts macht. Die Sofortlösung war ein Merge beim Speichern statt eines Überschreibens. Die eigentliche Lehre floss in die Struktur: Im vorbereiteten Supabase-Schema ist es eine Zeile pro Tag und Übung statt eines JSON-Blocks pro Tag. Damit kann der Konflikt nicht mehr entstehen, statt dass er nur behandelt wird, und das ist der Unterschied zwischen einem Bugfix und einer Entscheidung.

Stack

UI
  • React 18.3
  • Hooks und JSX
  • useMemo für Wochen- und Kalenderrechnung
Build
  • Vite 8.1
  • @vitejs/plugin-react
  • dynamischer Import für den Scanner
Scan
  • @zxing/browser
  • @zxing/library
  • EAN, UPC und QR im Browser
  • Open Food Facts
Styling
  • Inline-Styles
  • zentrales Farbsystem
  • handgezeichnetes SVG
  • 26 datengetriebene Animationen
PWA
  • Web-App-Manifest
  • Apple-Meta-Tags
  • Icons
  • Installation auf dem Homescreen
Data
  • localStorage
  • JSON-Backup
  • offline-tauglich
  • vorbereitet: Supabase mit Row Level Security
AI and auth
  • Anthropic Messages API
  • Claude Sonnet 4.6
  • Google Identity Services
  • OAuth 2.0 Token Client
  • Google Health API mit drei Nur-Lese-Scopes

Status and reading

In daily personal use as a PWA on the iPhone, development ongoing. Repository private, access on request.