Table of contents
About
SelfTrack is a personal health-progress tracking Progressive Web App (PWA) I built to make daily wellbeing check-ins as fast and frictionless as possible. It lets you monitor your weight loss, daily water intake, exercise minutes, and mood — all from a single dashboard, with no backend and no account required.
The entire goal was to build something you can open, update, and close in under 30 seconds. All data lives on your device in localStorage. Nothing leaves the browser, there are no servers, and the app works fully offline after the first load.
Github repository
https://github.com/obaranovskyi/SelfTrack
https://obaranovskyi.github.io/SelfTrack/
Preview
First-time onboarding
When you open SelfTrack for the first time (no startDate in local storage), a full-screen onboarding modal appears. It is not dismissable until you complete it — the app needs to know your starting weight before it can calculate progress.
You enter your starting weight in kilograms (for example 90.0), confirm, and the app stores both startDate (today's ISO date) and startWeight in local storage. From that point on, every subsequent open goes straight to the dashboard.
Weight tracker
The weight section shows a summary row at the top and an inline editor below it:
startWeight − currentWeight. If you have gained weight, this number is negative.[−] and [+]) adjust currentWeight by 0.1 kg per tap. The current value is shown between the buttons. The minimum allowed value is 0.1 kg.Every tap persists immediately to local storage. No save button required.
Exercise tracker
The exercise section displays an average and an inline editor for today's minutes:
startDate if the app is less than 165 days old).[+] adds 1 minute, [−] subtracts 1 minute. Today's total cannot go below 0.Exercise data is stored in an object keyed by ISO date (YYYY-MM-DD). On every write, entries older than 165 days are pruned automatically, so the storage footprint stays small.
Water tracker
The water section works similarly to exercise but resets each calendar day:
totalWaterDrunk ÷ daysElapsed where daysElapsed = today − startDate + 1 (minimum 1 to avoid divide-by-zero). Displayed in litres per day.[+] adds 0.1 L, [−] subtracts 0.1 L. Today's total cannot go below 0.0 L.When the app is opened on a new day, waterToday resets to { date: today, amount: 0.0 } without touching totalWaterDrunk. The running cumulative total is only ever adjusted by the delta of changes made to today's entry, which keeps the average consistent across day boundaries.
Mood tracker
The mood section lets you pick a value from 1 to 10 using a row of emoji buttons:
| 😞 | 😕 | 😐 | 🙂 | 😊 | 😄 | 😁 | 🤩 | 😍 | 🥳 |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Tapping an emoji sets today's mood. The selected emoji is highlighted; the others are dimmed. You can change your selection any number of times during the day.
Average mood is calculated from the last 90 days of recorded entries. Days with no entry are excluded from the average (they are not counted as zero). The average is shown to one decimal place alongside the corresponding emoji.
Mood data is stored in an object keyed by ISO date. Entries older than 90 days are pruned on each write.
Reset progress
A low-prominence "Reset the progress" button sits at the bottom of the page. Tapping it opens a confirmation modal that explains the action is irreversible.
To confirm, you must type today's date in YYYY-MM-DD format into an input field. The "Confirm Reset" button only activates when the entered date matches today's date exactly. On confirm, all selftrack_ keys are cleared from local storage and the app reloads into the onboarding flow.
This two-step confirmation prevents accidental resets while keeping the UI simple — no password, no email, just a date you already know.
PWA and offline support
SelfTrack is designed to be installed on your phone and used like a native app:
manifest.json provides the app name, icons (192×192 and 512×512), display: standalone, and a theme color so the browser chrome disappears after installation.Local storage schema
All keys use the selftrack_ prefix to avoid collisions with other apps running on the same origin.
| Key | Type | Description |
|---|---|---|
|
|
|
ISO date the app was first opened |
|
|
|
Initial weight in kg, set during onboarding |
|
|
|
Current weight in kg |
|
|
|
|
|
|
|
Cumulative litres since start |
|
|
|
|
|
|
|
|
