Free CdA calculator for cyclists: measure your drag area (CdA) and rolling resistance (Crr) from power meter field tests with Chung's virtual elevation method.
Sports & fitnessTypeScript · JavaScriptGitHub @mariuspopoviciOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Calculate CdA (Coefficient of Drag) and crr (tire rolling resistance) based on field testing data in the form of Garmin or compatible .FIT files.
Loading the full README.
Read the full README ↗MyCdA.app estimates your aerodynamic drag area (CdA) and rolling resistance (Crr) from rides recorded with a power meter, speed sensor and cycling computer. Compare runs to find out whether a change in position or equipment makes you faster.
Try it: mycda.app (free)
.fit and .csv files, including gzipped and zipped exports. Problem files say exactly why they can't be used, and failed or interrupted uploads can be retried.| Activities | Activity |
|---|---|
| Part | Technology |
|---|---|
Web app (web/) | React 19, TypeScript, Vite, Mantine, React Router, TanStack Query, Plotly, Leaflet |
Analysis core (web/src/core/) | Framework-free TypeScript: virtual elevation, fitting, wind model, air density, loop detection |
| Backend | Firebase Auth, Firestore, Storage and Hosting. Cloud Functions (functions/, Node 22) parse uploads and serve activity data |
| External data | Open-Meteo (weather, elevation) and OpenStreetMap (maps), with no API keys |
Architecture, design notes and decision records are in docs/.
You need Node 22+ and, for the emulator tests, Java 21+ and Chrome.
# web app
cd web
npm ci
cp .env.example .env.local # fill in your Firebase web config
npm run dev # http://localhost:5173
# or run everything locally against the Firebase emulators
npm --prefix ../tests/emulator ci
npm --prefix ../tests/emulator run emulators # terminal 1
npm run dev:emulators # terminal 2
Tests:
npm --prefix web test # analysis core, data and UI helpers (Vitest)
npm --prefix functions test # upload parsing (node --test)
npm --prefix tests/emulator test # security rules, functions end to end, browser tests (Playwright)
From the repository root, npm run dev, dev:emulators, emulators, build, lint, test (web and functions) and test:emulator forward to the packages; each package still installs its own dependencies with npm ci.
CI runs all of them on every push (.github/workflows/ci.yml).
Bump version in web/package.json on master, then tag that commit with the same version and push the tag:
git tag v2.1.0 && git push origin v2.1.0
The Deploy workflow checks that the tag matches the version and is on master, runs CI, and deploys to Firebase. The version shows in the app's footer.
.firebaserc at your project, and fill in web/.env.local from the project's web app config.firebase deploy. That deploys the Firestore and Storage rules, the functions, and hosting (which builds web/ first).The header row needs time, power and speed (km/h). It can also have airspeed, elevation, lap, lat and long. See the FAQ for details, or download the example file.
Questions and release notes: the MyCdA community. Bugs and ideas: GitHub issues.