The Problem

openfit is a desktop‑first Electron dashboard that visualises Fitbit data through the Google Health API. The codebase is functional but suffers from duplicated logic, oversized files, and CI that never runs the nine test files it contains. Without a license file the project’s redistribution rights are undefined, and the absence of dependency‑scan gates means a vulnerable package could slip into a build unnoticed.

What This Does

openfit is a private Electron app (React renderer, Tailwind v4, shadcn/Radix) that pulls Fitbit‑derived health metrics from Google Health API v4 and displays them in a small set of adaptive views (TodayView, SleepView, BodyView, etc.). The data flow is:

  1. Fitbit Air → Fitbit/Google Health mobile app → Google Health cloud (the only supported sync path; no direct Bluetooth third‑party access).
  2. Google Health API → openfit – the app defaults to the Google Health provider; a legacy Fitbit Web API adapter exists but is marked for deprecation in September 2026.
  3. The renderer (src/App.tsx) orchestrates OAuth‑driven sign‑in, view navigation, and assistant UI; the Electron main process (electron/main.cjs) handles OS‑level windows and preload scripts.

Key files and their responsibilities (from the responsibility block):

FileWhat it owns
src/App.tsxEntry point App; defines shiftDate, IconButton, navigation (changeDate, connect, disconnect); reads/writes files via navigateFromAssistant, SettingsDialog, PulseboardSidebar.
src/components/Views.tsx30 functions/classes including hasValue, SectionTitle, SignalRow, SupportingMetrics; renders the dashboard views.
src/types.ts20 type definitions: PageId, DataSource, HealthProvider, TimePoint, TrendPoint.
src/lib/utils.tsSingle exported cn (className utility) used from 15 other modules.
src/components/Charts.tsxChart‑related functions (finiteValues, useResponsiveChartWidth, lineDomain).
src/data/normalize.tsasObject, asArray, numeric, firstNumber, shortDay – the core data‑normalisation pipeline.
electron/google-health-service.cjs / electron/fitbit-legacy-service.cjsLegacy and Google‑Health adapters; contain 20 repeated 6‑line blocks (duplicate code).
src/lib/format.tsformatNumber, formatDecimal, formatMinutes, compactMinutes, clampPercent – high branching density (234 branches over 592 lines).
src/components/HealthAssistant.tsxAssistant UI: messageText, archiveData, statusLabel, queue management.
electron/main.cjsStarts the Electron app; called from npm run dev / npm run dist.

The internal call graph shows cn referenced from 61 places, asObject from 41, numeric from 39, and hasValue from 22+ view‑specific callers – indicating tight coupling around data formatting and presence checks.

How It Is Wired

Execution starts at src/App.tsx:114 (App component), which is called by nothing else in the repo. From App the flow fans out through navigateFromAssistant (reaches 9 functions) and disconnect (reaches 8 functions) to view components that call hasValue, formatNumber, formatDecimal, and the normalisation helpers (asObject, asArray). The Google‑Health service (electron/google-health-service.cjs) is invoked from the main process to fetch data; the legacy Fitbit adapter (electron/fitbit-legacy-service.cjs) remains only as a transitional fallback. The health assistant (src/components/HealthAssistant.tsx) and its backend (src/lib/health-assistant.ts) generate contextual messages and archive data, but neither writes to the filesystem outside the Electron sandbox.

A notable hub is src/data/normalize.ts – its asObject and numeric functions are called from many downstream modules, so changes there ripple widely. The oversized files (src/App.tsx, src/components/Views.tsx, electron/codex-service.cjs) each exceed 700 lines, making modifications high‑risk.

How To Use It

Setup (from package.json and README):

# clone the repo
git clone https://github.com/moses-y/openfit
cd openfit

# install dependencies (npm 10+, Node 22+)
npm install

Configuration – Google Cloud project required. The README walks through creating a project, enabling the Google Health API, setting an OAuth consent screen (external audience), and adding the Fitbit test account as an authorized user. No API key is needed; the app reuses the local Codex login if the Codex Desktop is installed.

Running it:

# start Vite dev server + Electron
npm run dev

Useful npm scripts (verbatim from README):

npm run build       # type‑check and bundle the renderer
npm test            # run normalizer and adapter tests
npm run capture:ui  # visual QA in Electron Chromium
npm run dist        # package for macOS/Windows/Linux

If you only need demo mode without Google Health, the app ships demo data; otherwise complete the OAuth flow before data appears.

Real‑World Use – A consultant can spin up a local instance to inspect a client’s Fitbit‑derived metrics (heart‑rate trends, sleep stages, activity calories) without touching the mobile app. By toggling the Google Health OAuth test user, the dashboard shows live signals; the assistant‑ui can be exercised by sending ad‑hoc queries through the Codex‑integrated health assistant.

Code Health & Issues

The static analysis produced the following deterministic findings:

  • [HIGH] Add a LICENSE – no licence file at the repository root; default is “all rights reserved,” blocking reuse in client engagements. Fix: add MIT or Apache-2.0 at the root.
  • [HIGH] Make CI invoke the test suite – nine test files exist but no workflow step runs npm test. A green check that never executes assertions erodes reviewer trust. Fix: add a test step to the existing .github/workflows/ci.yml.
  • [MEDIUM] Enable Dependabot or Renovate – only one manifest, no update bot configured. Unpatched vulnerabilities will remain until a manual audit. Fix: commit .github/dependabot.yml covering npm and github-actions.
  • [MEDIUM] Gate pull requests on dependency vulnerability scan – no dependency‑scan action in CI. A known‑vulnerable package could reach production. Fix: add dependency-review-action on pull_request or osv-scanner on push/schedule.
  • [MEDIUM] Set persist-credentials: false on checkout – the checkout step retains the token, allowing a malicious postinstall script to read pushable credentials. Fix: add with: persist-credentials: false and pass an explicit token only to the push step.
  • [LOW] Add convention files – missing .editorconfig, .gitattributes (text=auto, eol=lf), and formatter config. Inconsistent line endings and editor settings cause diff noise across contributors. Fix: add the three files with the prescribed contents.

No critical severity findings were raised; the codebase is functional but requires the above SDLC improvements to be production‑ready for client work.

The Bottom Line

openfit delivers a usable desktop dashboard for Fitbit data via Google Health, with a clear data‑flow map and functional React/Electron UI. The main risks are legal (missing license), CI gaps (tests never run), and code‑quality debt (duplication, oversized modules, high branching). These can be resolved with the listed fixes; after that the app is suitable for internal demos or client‑facing prototyping, provided the Google Health OAuth setup is completed.