Skip to main content
Version: 0.17

Dart Serialization Guide

Apache Fory™ Dart lets you serialize Dart objects to bytes and deserialize them back — including across services written in Java, Go, C#, Python, and other Fory-supported languages.

Why Fory Dart?

  • Cross-language: serialize in Dart, deserialize in Java, Go, C#, and more without writing any glue code
  • Fast: generated serializer code replaces reflection at runtime
  • Schema evolution: add or remove fields without breaking existing messages
  • Circular references: optional reference tracking handles shared or recursive object graphs
  • Escape hatch: write a manual serializer for any type that cannot be annotated

Quick Start

Requirements

  • Dart SDK 3.6 or later
  • build_runner (generates the serializer code)

Install

Add the dependency to your pubspec.yaml:

dependencies:
fory: ^0.17.0

dev_dependencies:
build_runner: ^2.4.0

Basic Example

Define your model, run the generator once, then serialize:

import 'package:fory/fory.dart';

part 'person.fory.dart';

enum Color {
red,
blue,
}

@ForyStruct()
class Person {
Person();

String name = '';
Int32 age = Int32(0);
Color favoriteColor = Color.red;
List<String> tags = <String>[];
}

void main() {
final fory = Fory();
PersonFory.register(
fory,
Color,
namespace: 'example',
typeName: 'Color',
);
PersonFory.register(
fory,
Person,
namespace: 'example',
typeName: 'Person',
);

final person = Person()
..name = 'Ada'
..age = Int32(36)
..favoriteColor = Color.blue
..tags = <String>['engineer', 'mathematician'];

final bytes = fory.serialize(person);
final roundTrip = fory.deserialize<Person>(bytes);
print(roundTrip.name);
}

Generate the companion file before running the program:

dart run build_runner build --delete-conflicting-outputs

PersonFory is generated by build_runner. The namespace and typeName values are how peers in other languages identify the same type — keep them stable once your service is in production.

API Overview

  • Fory(...) — create a serializer instance; create once and reuse it
  • fory.serialize(value) — returns Uint8List bytes
  • fory.deserialize<T>(bytes) — returns a T
  • @ForyStruct() — marks a class for code generation
  • @ForyField(...) — per-field options (skip, ID, nullability, references)
  • Integer wrappers: Int8, Int16, Int32, UInt8, UInt16, UInt32
  • Float wrappers: Float16, Float32
  • Time wrappers: LocalDate, Timestamp

Documentation

TopicDescription
ConfigurationRuntime options, compatible mode, and safety limits
Basic Serializationserialize, deserialize, generated registration, root graphs
Code Generation@ForyStruct, build runner, and generated namespaces
Type RegistrationID-based vs name-based registration and registration rules
Custom SerializersManual Serializer<T> implementations and unions
Field Configuration@ForyField, field IDs, nullability, references, polymorphism
Supported TypesBuilt-in xlang values, wrappers, collections, and structs
Schema EvolutionCompatible structs and evolving schemas
Cross-LanguageInteroperability rules and field alignment
TroubleshootingCommon errors, diagnostics, and validation steps