# Fitness & Wellness Kit

> Expo SDK 54 + Hono full-stack mobile fitness template. $99.

The OTF **Fitness & Wellness Kit** is a complete cross-platform fitness app starter. Expo
SDK 54 + Hono backend + Postgres + Better Auth + Stripe. Live web demo at
[fitness-preview.otf-kit.dev](https://fitness-preview.otf-kit.dev).

## Stack

| Layer       | Choice                                                         |
| ----------- | -------------------------------------------------------------- |
| Framework   | Expo SDK 54 + React 19 + Expo Router 6 (iOS · Android · Web)   |
| Routing     | Expo Router (file-based)                                       |
| Data        | TanStack Query                                                  |
| Server      | Hono 4 + Bun 1.3                                                |
| DB          | Postgres + Drizzle ORM 1.0-beta                                  |
| Auth        | Better Auth 1.6 + `@better-auth/expo` — email + Google + bearer (native) + cookies (web) + demo login |
| UI          | Plain RN + `react-native-svg` + kit-local primitives, with `@otfdashkit/ui-native` for shared blocks |
| Payments    | Stripe Checkout (one-time $149)                                  |
| Deploy      | Railway via `scripts/deploy-railway.sh` (web demo)<br />EAS Build for native binaries |

## Pre-built screens

The kit ships with **12 screens** modelled after Apple Fitness:

- **Auth**: login, signup
- **Onboarding**: welcome (first launch)
- **Summary** (LANDING): Activity Rings hero + 2x2 metric grid + recent workouts
- **Ring detail**: week strip + giant ring + intraday calorie bars
- **Metric detail**: D/W/M/Y SegmentedControl + 2 metric cards
- **Workout**: type chips + Start CTA + recent log
- **Workout start**: live timer + calorie/distance counters + End CTA
- **Workout detail**: completed-workout summary + delete
- **Sharing** (sub-screen of Profile): awards + friends activity feed
- **Goal**: StepperBig for daily move goal
- **Profile** (5th tab): avatar + all-time stats + settings + Sign out

The 5 bottom tabs: **Summary · Workout · Nutrition · Programs · Profile**.

## Reusable blocks

| Block               | Used for                                                          |
| ------------------- | ----------------------------------------------------------------- |
| `<ActivityRings />` | 3 concentric SVG rings (hero or week-strip mini)                  |
| `<WeekStrip />`     | 7 mini rings + day-letter labels                                   |
| `<StepperBig />`    | Big number with ⊖/⊕ circular buttons (goal screens)               |
| `<MetricCard />`    | Label + big-number value + unit + optional trend                   |
| `<SegmentedControl />` | D/W/M/Y capsule with sliding active pill                        |
| `<MiniBarChart />`  | Inline 7- or 24-bucket bar chart                                  |

## Database

- **5 Better-Auth tables**: `user`, `account`, `session`, `jwks`, `verification`
- **6 app tables**: `userPublic`, `dailyGoal`, `workoutType`, `workout`, `award`, `friendship`

## Demo + QR preview

[fitness-preview.otf-kit.dev](https://fitness-preview.otf-kit.dev) shows the kit in an iPhone
phone-frame plus an Expo Go QR card. Scan with Expo Go (Android) or Camera (iOS) to run the
preview channel build on your own phone instantly.

## Native builds

Native iOS / Android binaries are produced via EAS Build:

```bash
eas build --profile preview --platform ios
eas build --profile preview --platform android
```

The `eas.json` ships with `development`, `preview`, and `production` profiles. Submit to
TestFlight + Play Internal Testing via `eas submit`.

## Web safe-area shim — important

`app/_layout.tsx` wraps the kit in `<WebSafeAreaShim>` — a `SafeAreaInsetsContext.Provider`
that injects `top: 56` ONLY when iframed (the marketing preview at `fitness-preview.otf-kit.dev`
shows the kit inside a phone frame). On standalone web, this returns 0 so the kit reads
edge-to-edge. **Don't add layout-level `paddingTop` — go through `useSafeAreaInsets()` instead.**

## Deploy

```bash
bash scripts/deploy-railway.sh
```

This kit uses the **local-build pattern**: the script runs `bun run build` locally (Expo web
export + 1 KB Bun server bundle) before `railway up`. Building Expo + RN inside Docker takes
~15 minutes and pushes Railway's build cap; doing it locally takes ~1-2 minutes against the
warm monorepo cache.

## Required env

| Variable                | Purpose                                                         |
| ----------------------- | --------------------------------------------------------------- |
| `DATABASE_URL`          | Postgres connection string                                       |
| `BETTER_AUTH_SECRET`    | 32+ chars — signs sessions/JWTs                                  |
| `BETTER_AUTH_URL`       | Public origin                                                    |
| `STRIPE_SECRET_KEY`     | Stripe secret                                                    |
| `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret                                    |
| `RAILWAY_API_TOKEN`     | Read by deploy script                                            |
| `EXPO_PUBLIC_API_URL`   | (native builds only) Public API URL the iOS/Android binary points at |

Optional: `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET`. `DEMO_LOGIN_DISABLED=1`.

## Buy

[$99 on otf-kit.dev](https://otf-kit.dev/templates/fitness-kit) — or
[Starter Bundle](/docs/templates/starter-bundle) ($149 = all 4 full-stack kits + 15 landing templates + future kits).
