Social fitness tracking built on the AT Protocol.
Log workouts, track progress, and share with friends — all stored in your personal data repository.
- Log Workouts — Running, cycling, swimming, hiking, weightlifting, yoga, HIIT, and more. Track duration, distance, pace, sets, reps, and weight.
- Workout Plans — Create reusable strength training plans, share them, and start structured live sessions from them.
- Live Workout Tracking — Let friends follow along in real-time as you work out.
- Dashboard & Metrics — Customize your dashboard with widgets for weekly progress, goal tracking, activity heatmaps, and trends.
- Goals — Set distance, duration, workout count, or calorie targets on weekly, monthly, or yearly periods.
- Social Feed — Follow other users and see their workouts. Like, repost, and reply.
- Cross-post to Bluesky — Workouts automatically post to Bluesky with a rich summary card. Engagement flows back as notifications.
- Visibility Controls — Granular per-workout settings to hide calories, heart rate, notes, etc.
- Pebble Watch App — Log workouts from your wrist with plan sync, heart rate tracking, and live posting.
FitSky is a client-only application — there is no backend server. All data lives in each user's AT Protocol personal data repository (PDS), using custom lexicons for workouts, goals, plans, and profiles.
Cloudflare Pages hosts the SPA and runs edge functions for:
- OG image generation — Dynamic social preview cards using Satori + resvg-wasm
- Middleware — Injects OpenGraph meta tags into the SPA HTML for link previews (iMessage, Slack, Discord, etc.)
src/ React SPA source
pages/ Route pages (Dashboard, Feed, LogWorkout, etc.)
components/ Shared UI components
hooks/ React Query hooks for AT Protocol operations
api/ ATProto API functions (CRUD for workouts, plans, goals)
lib/ Utilities (colors, formatting, OAuth)
types/ TypeScript types for lexicon records
stores/ Zustand stores (auth, toast)
functions/ Cloudflare Pages Functions
_middleware.ts OG tag injection for all routes
api/og/ OG image generation endpoints
og/ Satori JSX components for OG cards
lexicons/ AT Protocol lexicon definitions (app.fitsky.*)
fitsky-pebble/ Pebble smartwatch app
src/c/ C source (workout tracking, menus, HR, GPS)
src/pkjs/ PebbleKit JS bridge (phone ↔ watch communication)
scripts/ Development tools
generate-og.tsx Local OG image preview generator
ios/ Capacitor iOS shell
android/ Capacitor Android shell
# Install dependencies
pnpm install
# Start dev server
pnpm devThe app runs at http://localhost:5173 and connects to the AT Protocol network. Sign in with your Bluesky account.
pnpm buildThe app deploys to Cloudflare Pages. The functions/ directory is automatically picked up for edge functions.
pnpm wrangler pages deploy dist --project-name fitsky-appTest OpenGraph card images locally before deploying:
# Preview a plan's OG card
pnpm og:plan <did> <rkey>
# Preview a workout's OG card
pnpm og:workout <did> <rkey>
# Custom output path
pnpm og:plan <did> <rkey> -o preview.pngOutput defaults to /tmp/og-plan-preview.png or /tmp/og-workout-preview.png.
See fitsky-pebble/ for the Pebble smartwatch app. Requires the Pebble SDK.
cd fitsky-pebble
pebble build
pebble install --emulator basaltAll data is stored using custom AT Protocol lexicons under the app.fitsky namespace.
| Lexicon | Description |
|---|---|
app.fitsky.workout |
Workout records with typed detail unions for cardio (distance, pace, elevation, steps, HR zones), strength (exercises with sets/reps/weight), flexibility, and HIIT. Supports live tracking, plan references, milestones, and per-field visibility. |
app.fitsky.workoutPlan |
Reusable workout templates for weightlifting, bodyweight, yoga, and HIIT with named exercises and target sets/reps. Supports cloning with attribution. |
app.fitsky.goal |
Fitness goals targeting distance, workout count, duration, or calories over weekly, monthly, or yearly periods. |
app.fitsky.blueskyPost |
Links a workout to its cross-posted Bluesky post via AT URIs, enabling engagement aggregation back into FitSky. |
app.fitsky.trend |
Dashboard trend snapshots with data points, summary stats, chart style, and an image blob for sharing. |
app.fitsky.profile |
FitSky-specific profile with custom banner and bio, falling back to Bluesky profile when not set. |
Lexicon definitions are in lexicons/.
- Frontend — React 19, React Router, TanStack Query, Zustand, Tailwind CSS 4, Lucide icons
- AT Protocol —
@atproto/api,@atproto/oauth-client-browser - OG Images — Satori (JSX → SVG), resvg-wasm (SVG → PNG), Cloudflare Pages Functions
- Native — Capacitor (iOS/Android shell), Apple Health / Google Health Connect via
@capgo/capacitor-health - Watch — Pebble C SDK with PebbleKit JS bridge
- Hosting — Cloudflare Pages
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
- Fork the repo
- Create your branch (
git checkout -b my-feature) - Make your changes
- Run
pnpm buildto verify - Open a pull request