The static profile supplies the message and field definitions used by the decoder
and the generated field reference. Pass includeUnmappedMessages: true to retain
fields outside that maintained surface by number and exact bytes; applications
that need all bytes for recognized messages can also opt into raw_messages.
Recognized message names, field names, enum values, wire types, scales,
offsets, arrays, and units come from the community-maintained profile in
src/profile.ts and src/profile-lookup-data.ts. Its maintenance and
verification contract is documented in
profile maintenance.
Public names use snake_case while preserving established alphanumeric tokens
such as n2, po2, and time128. Unmapped fields remain available by number
and exact bytes in unmapped_messages rather than receiving guessed names.
Named values follow the FIT messages, including FIT compressed-timestamp reconstruction. In particular,
product_name is not inferred from manufacturer and product, and record
elapsed_time and timer_time are added only when elapsedRecordField: true
is requested. Parsed FIT timestamps are Date objects, FIT bool fields keep
their numeric wire values, mask fields decode to { value, ...flags } objects,
unknown enum IDs remain numbers, and invalid entries retained inside FIT arrays
are null. All profile fields are optional because each FIT message definition
chooses which fields are present.
Profile scales are applied before the selected unit conversions. With default options, common decoded fields use these representations:
| Fields | Representation |
|---|---|
timestamp, start_time |
JavaScript Date |
position_lat, position_long |
Degrees |
distance, total_distance, altitude |
Metres |
speed, enhanced_speed, avg_speed |
Metres per second |
heart_rate, avg_heart_rate |
Beats per minute |
power, avg_power |
Watts |
temperature, avg_temperature |
Degrees Celsius |
total_elapsed_time, total_timer_time |
Seconds |
For example, a recorded distance of 1,000 metres and speed of 2.5 m/s decode as
1000 and 2.5 with defaults. Selecting lengthUnit: 'km' and
speedUnit: 'km/h' produces 1 and 9. These options affect their converted
field families; they do not rescale every numeric field. Consult the maintained
profile for other fields and their units.
Missing or FIT-invalid scalar fields are omitted. A valid zero reading remains zero, while invalid
entries retained inside arrays are null. Keep missing observations distinct
from a measured zero in downstream calculations.
Root metadata also depends on the file and output mode. Some legacy ParsedFit
declarations mark file_creator, user_profile or activity as required even
though they can be absent at runtime. Check presence before reading their fields.
JSON.stringify() turns Date values into strings. Consumers restoring that
JSON must handle date restoration themselves; the FIT parser reads binary input.
Keep original FIT bytes or a raw representation when exact wire values are needed.
Applications that need profile lookups independently of parsing can use the exported manufacturer, Garmin product, sport, sub-sport, and course-point helpers:
import {
getFitCoursePointId,
getFitGarminProductDisplayName,
getFitManufacturerName,
getFitSportId,
getFitSportName,
getFitSubSportId,
getFitSubSportName,
} from 'fit-file-parser'
getFitManufacturerName(1) // "garmin"
getFitGarminProductDisplayName(4655) // "Edge MTB"
getFitSportName(2) // "cycling"
getFitSubSportName(153) // "mountain_enduro"
getFitSportId('cycling') // 2
getFitSubSportId('indoor_cycling') // 6
getFitCoursePointId('rest_area') // 29
These helpers read the same maintained profile used by the decoder. The product
display helper is opt-in and does not synthesize or overwrite parsed
product_name values.
Unrecognized identifiers or names return null; a lookup does not guess the
nearest product or sport. For example, getFitSportId('not-a-sport') returns null.
Lookup-only consumers can import the same helpers from
fit-file-parser/profile without loading the parser entry point.
ParsedFit is a named export from the package root. The reference also shows its
nested field interfaces and enum types, but their source names are not all named
exports from the package. Derive nested types from the supported root type:
import type { ParsedFit } from 'fit-file-parser'
type RecordSample = NonNullable<ParsedFit['records']>[number]
type SessionSummary = NonNullable<ParsedFit['sessions']>[number]
The field reference follows the maintained profile. Presence in the reference does not establish that a particular watch exports that field; inspect the actual file. Unknown fields can be retained through raw and unmapped data.