Convert Garmin to ZWO
Take a Garmin Connect workout (GCN JSON) into a Zwift ZWO file so a plan from Garmin can run in Zwift. Use the free, in-browser Kaiord Editor (no account, no upload), or the CLI and TypeScript SDK. Conversions go through Kaiord's canonical KRD format and stay within round-trip tolerances (time ±1 s, power ±1 W or ±1 % FTP).
Three ways to convert
1. Editor (drag & drop)
Open kaiord.com/editor, drop your Garmin Connect workout file, choose ZWO as the export format, and download workout.zwo.
2. CLI
pnpm add -g @kaiord/cli
kaiord convert -i workout.gcn -o workout.zwo3. SDK
import { fromText, toText } from "@kaiord/core";
import { garminReader } from "@kaiord/garmin";
import { zwiftWriter } from "@kaiord/zwo";
import { readFile, writeFile } from "node:fs/promises";
const gcn = await readFile("workout.gcn", "utf-8");
const krd = await fromText(gcn, garminReader);
const zwo = await toText(krd, zwiftWriter);
await writeFile("workout.zwo", zwo);What survives the conversion
| Data | Garmin Connect (GCN) | ZWO (Zwift) | Result |
|---|---|---|---|
| Step order & names | workout steps | blocks (names as kaiord:name) | Preserved |
| Time durations | time durations | Duration seconds | Preserved (±1 s) |
| Distance durations | distance durations | time-based Duration | Converted to time; original kept under extensions.zwift |
| Power targets | watts | % FTP (Power fraction) | Converted using an assumed FTP (see below) |
| Repeats / intervals | repeat blocks | IntervalsT | Preserved |
| Steps without power | open / non-power target | FreeRide | Rendered as a free-ride segment |
| Heart-rate targets | bpm | — | Dropped (Zwift is power-based); kept under extensions.zwift |
Gotchas
Watts vs. % FTP. Garmin Connect stores power as watts; Zwift needs % FTP. The conversion divides watts by an assumed FTP (recorded as kaiord:assumedFtp, e.g. 250 W). If the percentages look off, rescale to your own FTP.
Non-power steps become free rides. ZWO is power-centric. Garmin steps that target heart rate or have no power target become FreeRide segments, since Zwift has no equivalent structured target for them.
Where do I get the .gcn file? GCN is Garmin Connect's workout JSON. Fetch it through the Garmin Connect API with @kaiord/garmin-connect (e.g. kaiord garmin list) or the Editor's Garmin integration.
Related
- Convert ZWO to Garmin — the reverse direction
- Convert FIT to ZWO — a device-file source
- GCN format · ZWO format
- All converters