# VYTA **VYTA** is a self-hosted health dashboard for Garmin data. It turns activity, sleep, recovery and training signals into a private daily overview with VYTA Age, pace of aging, training load, sleep insights, push notifications and local Garmin sync. The project is built for people who want the feel of a polished health app without sending their personal health archive to a third-party dashboard. ## Screenshots

VYTA overview dashboard

## What It Does - **VYTA Age**: a dynamic healthspan-style score based on VO2max, resting heart rate, HRV, sleep, steps and training signals. - **Healthspan view**: weekly period display, animated orb, pace of aging and contributor breakdowns. - **Today view**: Garmin-based recovery, strain, activity, sleep and energy summaries. - **Sleep view**: sleep score, duration, sleep debt and sleep phase details. - **Training view**: daily load, activity list, activity details and trend charts. - **Notifications**: optional push alerts for recovery, HRV deviation, sleep, new activities, VYTA Age changes and more. - **Garmin account setup in app**: each installation can connect its own Garmin account from settings. - **Private local data**: runtime data, Garmin credentials and token stores are kept outside Git. ## Repository Layout ```text app/vyta/ Next.js web app sync/vyta-sync/ Python Garmin collector, normalizer and scheduler ``` Runtime data belongs outside the repository, normally in `/data` inside the containers and mounted from your server, for example: ```text /mnt/tank/appdata/vyta/data ``` ## Privacy Model This repo intentionally does **not** include personal data or secrets. Never commit: ```text .env .env.local data/ private-data/ public/data/ garmin-credentials.json .garmin_tokens/ vyta-garmin.json vyta-data.json settings.json push-subscriptions.json notification-state.json ``` Garmin credentials are saved by the app to: ```text /data/garmin-credentials.json ``` Garmin session tokens are saved by the sync service to: ```text /data/.garmin_tokens/ ``` Both paths should be Docker volumes, not repository files. ## Configuration The web container expects environment variables for authentication, public URL, push notifications and internal sync communication. Common web variables: ```text VYTA_PUBLIC_URL VYTA_USERNAME VYTA_PASSWORD_HASH VYTA_SESSION_SECRET VYTA_DATA_PATH=/data/vyta-data.json VYTA_SETTINGS_PATH=/data/settings.json VYTA_PUSH_SUBSCRIPTIONS_PATH=/data/push-subscriptions.json VYTA_SYNC_STATUS_PATH=/data/sync-status.json VYTA_SYNC_REQUEST_PATH=/data/sync-request.json VYTA_INTERNAL_SYNC_SECRET NEXT_PUBLIC_VAPID_PUBLIC_KEY VAPID_PRIVATE_KEY VAPID_SUBJECT ``` Common sync variables: ```text VYTA_WEB_URL VYTA_INTERNAL_SYNC_SECRET VYTA_OUTPUT_PATH=/data/vyta-data.json VYTA_SYNC_INTERVAL_SECONDS=300 VYTA_SYNC_POLL_SECONDS=2 VYTA_SYNC_STATUS_PATH=/data/sync-status.json VYTA_SYNC_REQUEST_PATH=/data/sync-request.json VYTA_GARMIN_CREDENTIALS_PATH=/data/garmin-credentials.json VYTA_GARMIN_TOKENSTORE=/data/.garmin_tokens TZ=Europe/Stockholm ``` ## Build Web app: ```bash docker build -t vyta-web:latest app/vyta ``` Sync service: ```bash docker build -t vyta-sync:latest sync/vyta-sync ``` ## Run Example Web: ```bash docker run -d \ --name vyta \ --restart unless-stopped \ -p 3777:3000 \ -v /mnt/tank/appdata/vyta/data:/data \ --env-file /path/to/vyta.env \ vyta-web:latest ``` Sync: ```bash docker run -d \ --name vyta-sync \ --restart unless-stopped \ -v /mnt/tank/appdata/vyta/data:/data \ --env-file /path/to/vyta-sync.env \ vyta-sync:latest ``` ## Garmin Setup 1. Start the web app. 2. Sign in to VYTA. 3. Open **Inställningar**. 4. Connect Garmin under **Garmin-konto**. 5. The app stores credentials in `/data/garmin-credentials.json` and triggers sync. 6. The sync service uses `/data/.garmin_tokens/` after the first successful login. Each clone or deployment can connect its own Garmin account without changing the code. ## Development Web app: ```bash cd app/vyta npm install npm run dev ``` Sync service: ```bash cd sync/vyta-sync python -m venv .venv . .venv/bin/activate pip install -r requirements.txt python sync.py ``` ## Roadmap - Language selection in settings: Swedish and English UI. - More install-friendly Docker Compose template. - Better onboarding for first-time Garmin setup. - Optional multi-user support. - More Healthspan contributor tuning as more Garmin signals become available. ## Status VYTA is a personal, self-hosted health app. It is not a medical device and does not provide clinical advice.