Dart FIT SDK

A pure Dart port of the Garmin FIT SDK for encoding and decoding FIT (Flexible and Interoperable Data Transfer) files.

Pub Version License

Overview

The FIT (Flexible and Interoperable Data Transfer) protocol is a compact binary format designed for storing and sharing data from fitness, health, and sports devices. This library provides a complete Dart implementation for reading and writing FIT files, making it easy to integrate fitness data into your Dart or Flutter applications.

Features

  • Full FIT Protocol Support: Decode and encode FIT files with complete protocol compliance
  • Compressed Timestamp Headers: Efficient handling of compressed timestamps for compact file sizes
  • Developer Data Fields: Full support for custom developer-defined fields
  • CRC Verification: Built-in data integrity checks with CRC validation
  • Accumulated Fields: Proper handling of accumulated values (e.g., total distance)
  • Field Type Demotion: Automatic handling of variable-sized field definitions
  • Zero Dependencies: Pure Dart implementation with no external dependencies
  • Type-Safe: Strongly-typed message and field definitions
  • Cross-Platform: Works on all Dart platforms (Flutter, Web, Server, CLI)

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  fit_sdk: ^0.1.0

Then run:

dart pub get

Or for Flutter projects:

flutter pub get

Quick Start

Decoding a FIT File

import 'dart:io';
import 'package:fit_sdk/fit_sdk.dart';

void main() async {
  // Read FIT file
  final file = File('activity.fit');
  final bytes = await file.readAsBytes();

  // Create decoder
  final decoder = Decode();

  // Set up message listener
  decoder.onMesg = (Mesg mesg) {
    print('Message: ${mesg.name}');
    
    for (var field in mesg.fields) {
      if (field.value != null) {
        print('  ${field.name}: ${field.value} ${field.units}');
      }
    }
  };

  // Decode the file
  decoder.read(bytes);
}

Encoding a FIT File

import 'dart:io';
import 'package:fit_sdk/fit_sdk.dart';

void main() async {
  final encoder = Encode();
  encoder.open();

  // FIT epoch offset (seconds since 1989-12-31 00:00:00 UTC)
  const fitEpochOffset = 631065600;

  // Create File ID message (required)
  final fileIdMesg = Mesg.fromMesgNum(MesgNum.fileId);
  fileIdMesg.setFieldValue(0, 4); // type = activity
  fileIdMesg.setFieldValue(1, 1); // manufacturer = garmin
  fileIdMesg.setFieldValue(4, 
    (DateTime.now().millisecondsSinceEpoch ~/ 1000) - fitEpochOffset);

  final fileIdDef = MesgDefinition.fromMesg(fileIdMesg);
  encoder.writeMesgDefinition(fileIdDef);
  encoder.writeMesg(fileIdMesg);

  // Create Record message
  final recordMesg = Mesg.fromMesgNum(MesgNum.record);
  recordMesg.setFieldValue(253, 
    (DateTime.now().millisecondsSinceEpoch ~/ 1000) - fitEpochOffset);
  recordMesg.setFieldValue(0, (51.5074 * 11930464.7111).round()); // latitude
  recordMesg.setFieldValue(1, (-0.1278 * 11930464.7111).round()); // longitude
  recordMesg.setFieldValue(5, 1000); // distance (meters)
  recordMesg.setFieldValue(3, 150); // heart rate (bpm)

  final recordDef = MesgDefinition.fromMesg(recordMesg);
  encoder.writeMesgDefinition(recordDef);
  encoder.writeMesg(recordMesg);

  // Finalize and save
  final fitBytes = encoder.close();
  await File('output.fit').writeAsBytes(fitBytes);
}

Examples

The example/ directory contains complete working examples:

  • decode.dart: Demonstrates how to decode FIT files and display message data
  • encode.dart: Shows how to create FIT files with various message types
  • broadcaster.dart: Example of using the message broadcaster pattern

Run examples:

# Decode a FIT file
dart run example/decode.dart data/Activity.fit

# Create a new FIT file
dart run example/encode.dart output.fit

API Documentation

Core Classes

Decode

Decodes FIT files from binary data.

final decoder = Decode();
decoder.onMesg = (Mesg mesg) { /* handle message */ };
decoder.onMesgDefinition = (MesgDefinition def) { /* handle definition */ };
decoder.read(bytes);

Encode

Encodes FIT messages into binary format.

final encoder = Encode();
encoder.open();
encoder.writeMesgDefinition(definition);
encoder.writeMesg(message);
final bytes = encoder.close();

Mesg

Represents a FIT message with fields.

final mesg = Mesg.fromMesgNum(MesgNum.record);
mesg.setFieldValue(fieldNum, value);
final value = mesg.getFieldValue(fieldNum);

MesgBroadcaster

Event-based message handling with type-specific listeners.

final broadcaster = MesgBroadcaster();
broadcaster.addListener(MesgNum.record, (sender, args) {
  final recordMesg = RecordMesg(args.mesg);
  print('Heart Rate: ${recordMesg.heartRate}');
});

Message Types

The SDK includes strongly-typed message classes for all standard FIT message types:

  • FileIdMesg - File identification
  • RecordMesg - GPS and sensor data points
  • SessionMesg - Activity session summary
  • LapMesg - Lap information
  • ActivityMesg - Activity summary
  • EventMesg - Event markers
  • And many more...

FIT File Structure

A typical FIT file contains:

  1. File Header - Identifies the file as FIT format
  2. Message Definitions - Describe the structure of data messages
  3. Data Messages - Actual fitness/health data
  4. CRC - Data integrity checksum

Supported FIT Profile

This SDK supports the FIT Protocol as defined by Garmin. It includes:

  • All standard message types (Activity, Session, Lap, Record, etc.)
  • All standard field types and units
  • Developer data fields for custom extensions
  • Component field expansion
  • Accumulated field handling

Compatibility

  • Dart SDK: >= 3.0.0 < 4.0.0
  • Flutter: Compatible with all Flutter platforms (iOS, Android, Web, Desktop)
  • Platforms: Works on all Dart-supported platforms

Project Structure

fit_sdk/
├── lib/
│   ├── fit/              # Core FIT protocol implementation
│   │   ├── profile/      # Generated message and type definitions
│   │   ├── decode.dart   # FIT file decoder
│   │   ├── encode.dart   # FIT file encoder
│   │   └── ...
│   └── fit_sdk.dart      # Main library export
├── example/              # Example applications
├── data/                 # Sample FIT files for testing
└── doc/                  # Additional documentation

Differences from C# SDK

This Dart port maintains functional parity with the official Garmin C# FIT SDK while adapting to Dart idioms:

  • Uses Dart naming conventions (camelCase instead of PascalCase)
  • Leverages Dart's null safety features
  • Provides async/await support for file I/O
  • Includes Flutter-friendly APIs

All core features from the C# SDK have been ported, including:

  • ✅ Compressed timestamp headers
  • ✅ Developer data lookup
  • ✅ CRC verification
  • ✅ Accumulated field handling
  • ✅ Field type demotion

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

# Clone the repository
git clone https://github.com/floatinghotpot/dart_fit_sdk.git
cd dart_fit_sdk

# Install dependencies
dart pub get

# Run tests
dart test

# Run examples
dart run example/decode.dart data/Activity.fit

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Based on the Garmin FIT SDK
  • Ported from the official C# implementation
  • FIT Protocol © Garmin Ltd.

Resources

Support


Note: This is an unofficial port of the Garmin FIT SDK. For the official SDK and protocol documentation, please visit developer.garmin.com/fit.

Libraries

fit/accumulator
fit/buffered_mesg_broadcaster
fit/crc
fit/decode
fit/defines
fit/developer_data_key
fit/developer_data_lookup
fit/developer_field
fit/developer_field_definition
fit/developer_field_description
fit/encode
fit/field
fit/field_base
fit/field_component
fit/field_definition
fit/fit_exception
fit/fit_listener
fit/fit_messages
fit/i_mesg_broadcast_plugin
fit/mesg
fit/mesg_broadcaster
fit/mesg_definition
fit/profile
fit/profile/mesgs/aad_accel_features_mesg
fit/profile/mesgs/accelerometer_data_mesg
fit/profile/mesgs/activity_mesg
fit/profile/mesgs/ant_channel_id_mesg
fit/profile/mesgs/ant_rx_mesg
fit/profile/mesgs/ant_tx_mesg
fit/profile/mesgs/aviation_attitude_mesg
fit/profile/mesgs/barometer_data_mesg
fit/profile/mesgs/beat_intervals_mesg
fit/profile/mesgs/bike_profile_mesg
fit/profile/mesgs/blood_pressure_mesg
fit/profile/mesgs/cadence_zone_mesg
fit/profile/mesgs/camera_event_mesg
fit/profile/mesgs/capabilities_mesg
fit/profile/mesgs/chrono_shot_data_mesg
fit/profile/mesgs/chrono_shot_session_mesg
fit/profile/mesgs/climb_pro_mesg
fit/profile/mesgs/connectivity_mesg
fit/profile/mesgs/course_mesg
fit/profile/mesgs/course_point_mesg
fit/profile/mesgs/developer_data_id_mesg
fit/profile/mesgs/device_aux_battery_info_mesg
fit/profile/mesgs/device_info_mesg
fit/profile/mesgs/device_settings_mesg
fit/profile/mesgs/dive_alarm_mesg
fit/profile/mesgs/dive_apnea_alarm_mesg
fit/profile/mesgs/dive_gas_mesg
fit/profile/mesgs/dive_settings_mesg
fit/profile/mesgs/dive_summary_mesg
fit/profile/mesgs/event_mesg
fit/profile/mesgs/exd_data_concept_configuration_mesg
fit/profile/mesgs/exd_data_field_configuration_mesg
fit/profile/mesgs/exd_screen_configuration_mesg
fit/profile/mesgs/exercise_title_mesg
fit/profile/mesgs/field_capabilities_mesg
fit/profile/mesgs/field_description_mesg
fit/profile/mesgs/file_capabilities_mesg
fit/profile/mesgs/file_creator_mesg
fit/profile/mesgs/file_id_mesg
fit/profile/mesgs/goal_mesg
fit/profile/mesgs/gps_metadata_mesg
fit/profile/mesgs/gyroscope_data_mesg
fit/profile/mesgs/hr_mesg
fit/profile/mesgs/hr_zone_mesg
fit/profile/mesgs/hrm_profile_mesg
fit/profile/mesgs/hrv_mesg
fit/profile/mesgs/hrv_status_summary_mesg
fit/profile/mesgs/hrv_value_mesg
fit/profile/mesgs/hsa_accelerometer_data_mesg
fit/profile/mesgs/hsa_body_battery_data_mesg
fit/profile/mesgs/hsa_configuration_data_mesg
fit/profile/mesgs/hsa_event_mesg
fit/profile/mesgs/hsa_gyroscope_data_mesg
fit/profile/mesgs/hsa_heart_rate_data_mesg
fit/profile/mesgs/hsa_respiration_data_mesg
fit/profile/mesgs/hsa_spo2_data_mesg
fit/profile/mesgs/hsa_step_data_mesg
fit/profile/mesgs/hsa_stress_data_mesg
fit/profile/mesgs/hsa_wrist_temperature_data_mesg
fit/profile/mesgs/jump_mesg
fit/profile/mesgs/lap_mesg
fit/profile/mesgs/length_mesg
fit/profile/mesgs/magnetometer_data_mesg
fit/profile/mesgs/max_met_data_mesg
fit/profile/mesgs/memo_glob_mesg
fit/profile/mesgs/mesg_capabilities_mesg
fit/profile/mesgs/mesgs
fit/profile/mesgs/met_zone_mesg
fit/profile/mesgs/monitoring_hr_data_mesg
fit/profile/mesgs/monitoring_info_mesg
fit/profile/mesgs/monitoring_mesg
fit/profile/mesgs/nmea_sentence_mesg
fit/profile/mesgs/obdii_data_mesg
fit/profile/mesgs/ohr_settings_mesg
fit/profile/mesgs/one_d_sensor_calibration_mesg
fit/profile/mesgs/pad_mesg
fit/profile/mesgs/power_zone_mesg
fit/profile/mesgs/raw_bbi_mesg
fit/profile/mesgs/record_mesg
fit/profile/mesgs/respiration_rate_mesg
fit/profile/mesgs/schedule_mesg
fit/profile/mesgs/sdm_profile_mesg
fit/profile/mesgs/segment_file_mesg
fit/profile/mesgs/segment_id_mesg
fit/profile/mesgs/segment_lap_mesg
fit/profile/mesgs/segment_leaderboard_entry_mesg
fit/profile/mesgs/segment_point_mesg
fit/profile/mesgs/session_mesg
fit/profile/mesgs/set_mesg
fit/profile/mesgs/skin_temp_overnight_mesg
fit/profile/mesgs/slave_device_mesg
fit/profile/mesgs/sleep_assessment_mesg
fit/profile/mesgs/sleep_disruption_overnight_severity_mesg
fit/profile/mesgs/sleep_disruption_severity_period_mesg
fit/profile/mesgs/sleep_level_mesg
fit/profile/mesgs/software_mesg
fit/profile/mesgs/speed_zone_mesg
fit/profile/mesgs/split_mesg
fit/profile/mesgs/split_summary_mesg
fit/profile/mesgs/spo2_data_mesg
fit/profile/mesgs/sport_mesg
fit/profile/mesgs/stress_level_mesg
fit/profile/mesgs/tank_summary_mesg
fit/profile/mesgs/tank_update_mesg
fit/profile/mesgs/three_d_sensor_calibration_mesg
fit/profile/mesgs/time_in_zone_mesg
fit/profile/mesgs/timestamp_correlation_mesg
fit/profile/mesgs/totals_mesg
fit/profile/mesgs/training_file_mesg
fit/profile/mesgs/training_settings_mesg
fit/profile/mesgs/user_profile_mesg
fit/profile/mesgs/video_clip_mesg
fit/profile/mesgs/video_description_mesg
fit/profile/mesgs/video_frame_mesg
fit/profile/mesgs/video_mesg
fit/profile/mesgs/video_title_mesg
fit/profile/mesgs/watchface_settings_mesg
fit/profile/mesgs/weather_alert_mesg
fit/profile/mesgs/weather_conditions_mesg
fit/profile/mesgs/weight_scale_mesg
fit/profile/mesgs/workout_mesg
fit/profile/mesgs/workout_session_mesg
fit/profile/mesgs/workout_step_mesg
fit/profile/mesgs/zones_target_mesg
fit/profile/types/activity
fit/profile/types/activity_class
fit/profile/types/activity_level
fit/profile/types/activity_subtype
fit/profile/types/activity_type
fit/profile/types/analog_watchface_layout
fit/profile/types/ant_channel_id
fit/profile/types/ant_network
fit/profile/types/antplus_device_type
fit/profile/types/attitude_stage
fit/profile/types/attitude_validity
fit/profile/types/auto_activity_detect
fit/profile/types/auto_sync_frequency
fit/profile/types/autolap_trigger
fit/profile/types/autoscroll
fit/profile/types/backlight_mode
fit/profile/types/backlight_timeout
fit/profile/types/banded_exercises_exercise_name
fit/profile/types/battery_status
fit/profile/types/battle_rope_exercise_name
fit/profile/types/bench_press_exercise_name
fit/profile/types/bike_exercise_name
fit/profile/types/bike_light_beam_angle_mode
fit/profile/types/bike_light_network_config_type
fit/profile/types/bike_outdoor_exercise_name
fit/profile/types/ble_device_type
fit/profile/types/body_location
fit/profile/types/bp_status
fit/profile/types/calf_raise_exercise_name
fit/profile/types/camera_event_type
fit/profile/types/camera_orientation_type
fit/profile/types/cardio_exercise_name
fit/profile/types/carry_exercise_name
fit/profile/types/ccr_setpoint_switch_mode
fit/profile/types/checksum
fit/profile/types/chop_exercise_name
fit/profile/types/climb_pro_event
fit/profile/types/comm_timeout_type
fit/profile/types/connectivity_capabilities
fit/profile/types/core_exercise_name
fit/profile/types/course_capabilities
fit/profile/types/course_point
fit/profile/types/crunch_exercise_name
fit/profile/types/curl_exercise_name
fit/profile/types/date_mode
fit/profile/types/date_time
fit/profile/types/day_of_week
fit/profile/types/deadlift_exercise_name
fit/profile/types/device_index
fit/profile/types/digital_watchface_layout
fit/profile/types/display_heart
fit/profile/types/display_measure
fit/profile/types/display_orientation
fit/profile/types/display_position
fit/profile/types/display_power
fit/profile/types/dive_alarm_type
fit/profile/types/dive_alert
fit/profile/types/dive_backlight_mode
fit/profile/types/dive_gas_mode
fit/profile/types/dive_gas_status
fit/profile/types/elliptical_exercise_name
fit/profile/types/event
fit/profile/types/event_type
fit/profile/types/exd_data_units
fit/profile/types/exd_descriptors
fit/profile/types/exd_display_type
fit/profile/types/exd_layout
fit/profile/types/exd_qualifiers
fit/profile/types/exercise_category
fit/profile/types/favero_product
fit/profile/types/file
fit/profile/types/file_flags
fit/profile/types/fit_base_type
fit/profile/types/fit_base_unit
fit/profile/types/fitness_equipment_state
fit/profile/types/floor_climb_exercise_name
fit/profile/types/flye_exercise_name
fit/profile/types/garmin_product
fit/profile/types/gas_consumption_rate_type
fit/profile/types/gender
fit/profile/types/goal
fit/profile/types/goal_recurrence
fit/profile/types/goal_source
fit/profile/types/hip_raise_exercise_name
fit/profile/types/hip_stability_exercise_name
fit/profile/types/hip_swing_exercise_name
fit/profile/types/hr_type
fit/profile/types/hr_zone_calc
fit/profile/types/hrv_status
fit/profile/types/hyperextension_exercise_name
fit/profile/types/indoor_bike_exercise_name
fit/profile/types/indoor_row_exercise_name
fit/profile/types/intensity
fit/profile/types/ladder_exercise_name
fit/profile/types/language
fit/profile/types/language_bits_0
fit/profile/types/language_bits_1
fit/profile/types/language_bits_2
fit/profile/types/language_bits_3
fit/profile/types/language_bits_4
fit/profile/types/lap_trigger
fit/profile/types/lateral_raise_exercise_name
fit/profile/types/left_right_balance
fit/profile/types/left_right_balance_100
fit/profile/types/leg_curl_exercise_name
fit/profile/types/leg_raise_exercise_name
fit/profile/types/length_type
fit/profile/types/local_date_time
fit/profile/types/local_device_type
fit/profile/types/lunge_exercise_name
fit/profile/types/manufacturer
fit/profile/types/max_met_category
fit/profile/types/max_met_heart_rate_source
fit/profile/types/max_met_speed_source
fit/profile/types/mesg_count
fit/profile/types/mesg_num
fit/profile/types/message_index
fit/profile/types/move_exercise_name
fit/profile/types/no_fly_time_mode
fit/profile/types/olympic_lift_exercise_name
fit/profile/types/plank_exercise_name
fit/profile/types/plyo_exercise_name
fit/profile/types/pose_exercise_name
fit/profile/types/power_phase_type
fit/profile/types/projectile_type
fit/profile/types/pull_up_exercise_name
fit/profile/types/push_up_exercise_name
fit/profile/types/pwr_zone_calc
fit/profile/types/radar_threat_level_type
fit/profile/types/rider_position_type
fit/profile/types/row_exercise_name
fit/profile/types/run_exercise_name
fit/profile/types/run_indoor_exercise_name
fit/profile/types/sandbag_exercise_name
fit/profile/types/schedule
fit/profile/types/segment_delete_status
fit/profile/types/segment_lap_status
fit/profile/types/segment_leaderboard_type
fit/profile/types/segment_selection_type
fit/profile/types/sensor_type
fit/profile/types/session_trigger
fit/profile/types/set_type
fit/profile/types/shoulder_press_exercise_name
fit/profile/types/shoulder_stability_exercise_name
fit/profile/types/shrug_exercise_name
fit/profile/types/side
fit/profile/types/sit_up_exercise_name
fit/profile/types/sled_exercise_name
fit/profile/types/sledge_hammer_exercise_name
fit/profile/types/sleep_disruption_severity
fit/profile/types/sleep_level
fit/profile/types/source_type
fit/profile/types/split_type
fit/profile/types/spo2_measurement_type
fit/profile/types/sport
fit/profile/types/sport_bits_0
fit/profile/types/sport_bits_1
fit/profile/types/sport_bits_2
fit/profile/types/sport_bits_3
fit/profile/types/sport_bits_4
fit/profile/types/sport_bits_5
fit/profile/types/sport_bits_6
fit/profile/types/sport_event
fit/profile/types/squat_exercise_name
fit/profile/types/stair_stepper_exercise_name
fit/profile/types/stroke_type
fit/profile/types/sub_sport
fit/profile/types/supported_exd_screen_layouts
fit/profile/types/suspension_exercise_name
fit/profile/types/swim_stroke
fit/profile/types/switch
fit/profile/types/tap_sensitivity
fit/profile/types/time_mode
fit/profile/types/time_zone
fit/profile/types/timer_trigger
fit/profile/types/tire_exercise_name
fit/profile/types/tissue_model_type
fit/profile/types/tone
fit/profile/types/total_body_exercise_name
fit/profile/types/triceps_extension_exercise_name
fit/profile/types/turn_type
fit/profile/types/types
fit/profile/types/user_local_id
fit/profile/types/warm_up_exercise_name
fit/profile/types/watchface_mode
fit/profile/types/water_type
fit/profile/types/weather_report
fit/profile/types/weather_severe_type
fit/profile/types/weather_severity
fit/profile/types/weather_status
fit/profile/types/weight
fit/profile/types/wkt_step_duration
fit/profile/types/wkt_step_target
fit/profile/types/workout_capabilities
fit/profile/types/workout_equipment
fit/profile/types/workout_hr
fit/profile/types/workout_power
fit/protocol_validator
fit/subfield
fit_sdk
FIT SDK for Dart
utility/endian_binary_reader
utility/endian_binary_writer