Generic "JSON to CSV" tools choke on Fitbit and Google Health exports because the JSON is nested, multi-file, and date-aligned across files. This converter is built specifically for Fitbit-shaped JSON, which is why it produces usable CSV instead of garbage.
This page is for people who've opened their Fitbit or Google Health Takeout export and found themselves staring at a folder of .json files. The obvious next thought is "I need a JSON to CSV converter." Most generic ones won't work, here's why, and here's what does.
If you've tried a generic online JSON to CSV converter on a Fitbit file, you've probably seen one of three results: an error message, a CSV with one giant unreadable cell, or a CSV that looks plausible but has dates in 1970.
Reason one: nested structure. Fitbit JSON isn't flat. Each file has an array of date-stamped objects, sometimes with nested sub-objects (e.g. heart rate data has a value object that contains caloriesOut, mets, level, and a customHeartRateZones array). Generic converters either flatten everything badly or refuse to flatten at all.
Reason two: multi-file joins. Your "daily steps" CSV needs steps, distance, calories and active minutes joined together by date. Those metrics live in separate JSON files. A generic converter handles one file at a time and can't join across files.
Reason three: timezone and unit conversion. Raw Fitbit JSON values are in centimetres (distance) and pounds (weight) regardless of your locale. Timestamps are UTC. A generic converter outputs the raw values and dates, which produces a CSV that's technically correct but functionally useless.
The Wearable Converter is built around the specific shape of Fitbit JSON. It handles the nesting, joins across files on date, and converts units and timezones automatically.
The shape varies slightly between data types but the common pattern is an array of objects, each with a dateTime key and a value key. Activity files look something like:
[
{
"dateTime": "2025-06-08T00:00:00",
"value": "9847"
},
{
"dateTime": "2025-06-09T00:00:00",
"value": "12402"
}
]
Body composition files have a slightly different shape with multiple values per record:
[
{
"logId": 1234567890,
"weight": 165.5,
"bmi": 24.2,
"fat": 18.5,
"date": "06/09/25",
"time": "07:30:15",
"source": "Aria"
}
]
The converter handles both shapes and roughly 8 other data type variations across the Fitbit JSON export schema.
Same problem, different framings. Helpful if your specific search query isn't quite this one.