Convert ZWO to TCX
Turn a Zwift ZWO workout into a TCX (Training Center XML) file — the format most training platforms accept for import. 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, cadence ±1 rpm).
Three ways to convert
1. Editor (drag & drop)
Open kaiord.com/editor, drop your .zwo file, choose TCX as the export format, and download workout.tcx.
2. CLI
pnpm add -g @kaiord/cli
kaiord convert -i workout.zwo -o workout.tcx3. SDK
import { fromText, toText } from "@kaiord/core";
import { zwiftReader } from "@kaiord/zwo";
import { tcxWriter } from "@kaiord/tcx";
import { readFile, writeFile } from "node:fs/promises";
const zwo = await readFile("workout.zwo", "utf-8");
const krd = await fromText(zwo, zwiftReader);
const tcx = await toText(krd, tcxWriter);
await writeFile("workout.tcx", tcx);What survives the conversion
| Data | ZWO (Zwift) | TCX | Result |
|---|---|---|---|
| Step order & names | blocks | <Step> / <Name> | Preserved |
| Time durations | Duration seconds | Time_t seconds | Preserved (±1 s) |
| Power targets | % FTP (Power fraction) | — | Dropped — TCX workouts have no power target |
| Ramps | Warmup / Cooldown / Ramp | untargeted steps | Duration preserved; the power ramp is dropped |
| Cadence targets | limited | Cadence_t | Preserved when present (±1 rpm) |
| Free-ride segments | FreeRide | untargeted step | Preserved as a step without a target |
| Repeats / intervals | IntervalsT | Repeat_t | Preserved |
Gotchas
My power targets disappeared. The TCX workout schema (Garmin Training Center) defines heart-rate, speed, and cadence targets only — there is no power target. Zwift workouts are power-based (% FTP), so the power targets have nowhere to land and are dropped; the step structure and durations remain. To keep power, convert to FIT or Garmin Connect instead.
So why convert to TCX at all? TCX is a widely accepted interchange format — TrainingPeaks, Strava, and Garmin Connect all import it — so it is useful when you want the workout's structure (steps, durations, intervals) on a platform that reads TCX but cannot read ZWO. Just expect the power targets not to come along.
Cadence. If your ZWO carries cadence targets, they map to TCX Cadence_t targets. Most Zwift workouts are pure power, so this is often empty.
Related
- Convert TCX to ZWO — the reverse direction
- Convert ZWO to FIT — keep power targets
- ZWO format · TCX format
- All converters