Demo app for exercising the real @clipin/convex-wearables Convex component.
The @clipin/convex-wearables component is open source: clipinfit/convex-wearables
The demo mounts Garmin webhook and OAuth callback routes via registerRoutes(...) from the package, so the host app does not duplicate Garmin HTTP handler logic locally.
This demo uses the real @clipin/convex-wearables package and the Garmin routes it exposes, so you need the same core variables that the component setup expects.
Set the Convex URL before running the demo. Add both Garmin credentials to enable Garmin connections and webhooks. The dashboard can run without Garmin credentials.
# Created or updated by `npx convex dev`
NEXT_PUBLIC_CONVEX_URL=https://<your-deployment>.convex.cloud
# Optional Garmin credentials used by the component client and mounted HTTP routes
GARMIN_CLIENT_ID=...
GARMIN_CLIENT_SECRET=...
# Used to build the Garmin OAuth callback URL inside Convex
CONVEX_SITE_URL=https://<your-deployment>.convex.site
# Recommended for correct post-auth redirects
# Local development falls back to http://localhost:3000 if omitted
NEXT_PUBLIC_APP_URL=http://localhost:3000NEXT_PUBLIC_CONVEX_URL belongs in .env.local. To use Garmin, set both credentials and CONVEX_SITE_URL in the Convex runtime used by this demo.
For the full component setup, provider configuration, and webhook route details, read the upstream docs:
Start the Next.js app:
npm run devIn a separate terminal, start Convex:
npx convex devThe Convex dashboard shows logs for the dev deployment, but it does not pull code changes by itself. The local npx convex dev process is what uploads function changes.
This demo includes a stored 30-day time-series retention policy with tighter compaction for dense metrics such as heart rate, SpO2, respiration, Garmin stress, and Garmin body battery.
Apply it to the current Convex deployment with:
npx convex run wearablesPolicy:applyDemoTimeSeriesStoragePolicy '{}'Inspect the currently stored policy with:
npx convex run wearablesPolicy:getTimeSeriesStoragePolicy '{}'This app uses the real @clipin/convex-wearables package from npm rather than a local file dependency.
When you want to test a newer component version:
-
Update the package version in
package.json. -
Reinstall dependencies:
npm install- Restart or rerun Convex so the updated component code is uploaded and codegen is refreshed:
npx convex devIf convex dev is already running, stop it and start it again after updating the package.
If the demo app is still calling old component code, inspect the generated component bindings:
rg "garminWebhooks|processPushPayload" convex/_generated/api.d.tsIf a new component module or function is missing there, the demo app has not picked up the installed component version yet.
An error like Couldn't resolve wearables.garminWebhooks.processPushPayload usually means this generated file is still stale.
One more constraint: the host app can only call component functions that are exposed as public query, mutation, or action. Component internalQuery, internalMutation, and internalAction functions are not callable through components.wearables.*.

