fory 1.1.0-rc1 copy "fory: ^1.1.0-rc1" to clipboard
fory: ^1.1.0-rc1 copied to clipboard

Cross-language Apache Fory runtime for Dart with generated serializers, schema evolution, and custom type support.

Apache Fory™ Dart #

Apache Fory™ Dart is the Dart xlang runtime for Apache Fory™. It reads and writes Fory's cross-language wire format and is designed around generated serializers for annotated Dart models, with customized serializers available for advanced use cases.

Features #

  • Cross-language serialization with the Fory xlang format
  • Dart VM/AOT, Flutter, and web platform support
  • Generated serializers for annotated structs and enums
  • Compatible mode for schema evolution
  • Optional reference tracking for shared and circular object graphs
  • Manual serializers for external types, custom payloads, and unions
  • Explicit exact-width value classes for Int64, Uint64, Float32, LocalDate, and Timestamp, plus Duration support

Getting Started #

Add fory to your package dependencies.

dependencies:
  fory: ^1.1.0-rc1

dev_dependencies:
  build_runner: ^2.4.13

Basic Usage #

Use @ForyStruct() for generated struct serializers and include the generated part file.

import 'package:fory/fory.dart';

part 'person.fory.dart';

enum Color {
  red,
  blue,
}

@ForyStruct()
class Person {
  Person();

  String name = '';

  @ForyField(type: Int32Type())
  int age = 0;
  Color favoriteColor = Color.red;
  List<String> tags = <String>[];
}

void main() {
  final fory = Fory();

  PersonForyModule.register(
    fory,
    Color,
    namespace: 'example',
    typeName: 'Color',
  );
  PersonForyModule.register(
    fory,
    Person,
    namespace: 'example',
    typeName: 'Person',
  );

  final person = Person()
    ..name = 'Ada'
    ..age = 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

Type Registration #

Generated types register through the generated library namespace. The namespace class is named <FileName>ForyModule based on the source file that contains the annotated types.

PersonForyModule.register(fory, Person, id: 100);

Or use namespace and type name registration:

PersonForyModule.register(
  fory,
  Person,
  namespace: 'example',
  typeName: 'Person',
);

Exactly one registration mode is required:

  • id: ...
  • namespace: ... and typeName: ...

Keep the same registration identity on all runtimes that exchange the type.

Configuration #

final fory = Fory(
  maxDepth: 256,
  maxCollectionSize: 1 << 20,
  maxBinarySize: 64 * 1024 * 1024,
);
Option Default Description
compatible true Enables compatible struct encoding for schema evolution
checkStructVersion false Validates struct version in schema-consistent mode
maxDepth 256 Maximum nesting depth per operation
maxCollectionSize 1 << 20 Maximum collection and map payload size
maxBinarySize 64 << 20 Maximum binary payload size

Reference Tracking #

Enable root-level reference tracking only when the root value itself is a graph or container that needs shared-reference tracking.

final shared = String.fromCharCodes('shared'.codeUnits);
final bytes = fory.serialize(<Object?>[shared, shared], trackRef: true);
final roundTrip = fory.deserialize<List<Object?>>(bytes);

For generated structs, prefer field-level reference metadata:

@ForyStruct()
class NodeList {
  NodeList();

  @ForyField(ref: true)
  List<Object?> values = <Object?>[];
}

Field Annotations #

@ForyField() controls per-field serialization behavior:

Option Description
skip Skip the field during serialization
id Stable field ID for compatible-mode evolution
nullable Override nullability inference
ref Enable reference tracking for this field
dynamic Control whether runtime type metadata is written

type: is the canonical override surface for nested field semantics:

@MapField(
  value: ListType(
    element: Int32Type(encoding: Encoding.fixed),
  ),
)
Map<String, List<int?>> nested = <String, List<int?>>{};

Customized Serializers #

Use Serializer<T> when a type cannot use generated struct support or when you need custom wire behavior.

import 'package:fory/fory.dart';

final class Person {
  Person(this.name, this.age);

  final String name;
  final int age;
}

final class PersonSerializer extends Serializer<Person> {
  const PersonSerializer();

  @override
  void write(WriteContext context, Person value) {
    final buffer = context.buffer;
    buffer.writeUtf8(value.name);
    buffer.writeInt64FromInt(value.age);
  }

  @override
  Person read(ReadContext context) {
    final buffer = context.buffer;
    return Person(buffer.readUtf8(), buffer.readInt64AsInt());
  }
}

void main() {
  final fory = Fory();
  fory.registerSerializer(
    Person,
    const PersonSerializer(),
    namespace: 'example',
    typeName: 'Person',
  );

  final bytes = fory.serialize(Person('Ada', 36));
  final roundTrip = fory.deserialize<Person>(bytes);
  print(roundTrip.name);
}

Type Mapping #

Dart has no native fixed-width 8/16/32-bit integer, unsigned 64-bit integer, or reduced/single-precision float scalar types. Fory Dart uses plain Dart int or double plus field annotations for exact wire widths, keeps Int64 and Uint64 for full-range 64-bit values, and keeps Float32 for single-precision rounding. For 16-bit floating-point arrays, Dart exposes Float16List and Bfloat16List as contiguous fixed-length buffers.

Fory xlang type Dart type
bool bool
int8 int + @ForyField(type: Int8Type())
int16 int + @ForyField(type: Int16Type())
int32 int + @ForyField(type: Int32Type())
int64 int or fory.Int64
uint8 int + @ForyField(type: Uint8Type())
uint16 int + @ForyField(type: Uint16Type())
uint32 int + @ForyField(type: Uint32Type())
uint64 fory.Uint64 (wrapper)
float16 double + @ForyField(type: Float16Type())
bfloat16 double + @ForyField(type: Bfloat16Type())
float32 fory.Float32 (wrapper)
float64 double
string String
binary Uint8List
duration Duration
local_date LocalDate
timestamp Timestamp
list List
set Set
map Map
enum enum
named_struct class
array BoolList + @ArrayField(element: BoolType())
array Int8List
array Int16List
array Int32List
array Int64List
array Uint8List
array Uint16List
array Uint32List
array Uint64List
array Float16List
array Bfloat16List
array Float32List
array Float64List

Public API #

The main exported API includes:

  • Fory — main serialization facade
  • Config — runtime configuration
  • ForyStruct, ForyField, ListField, SetField, MapField — struct annotations
  • ForyUnion — union type annotation
  • Serializer, UnionSerializer, EnumSerializer — serializer base classes
  • Buffer, WriteContext, ReadContext — low-level I/O
  • TypeSpec, DeclaredType, ListType, SetType, MapType — nested type annotations
  • Int8Type, Int16Type, Int32Type, Int64Type, Uint8Type, Uint16Type, Uint32Type, Uint64Type, Float16Type, Bfloat16Type, Float32Type — scalar wire-type overrides
  • Numeric value wrappers: Int64, Uint64, Float32
  • Temporal types: LocalDate, Timestamp, Duration

Cross-Language Notes #

  • The Dart runtime only supports xlang payloads.
  • Register user-defined types before serialization or deserialization.
  • Keep numeric IDs or namespace + typeName mappings consistent across languages.
  • Use Dart int plus @ForyField(type: ...) for 8/16/32-bit integer fields, Dart double plus Float16Type or Bfloat16Type for 16-bit floating-point fields, and Int64 / Uint64 when full-range 64-bit values matter.

For the xlang wire format and type mapping details, see the Apache Fory specification.

For the full Dart guide, see https://fory.apache.org/docs/guide/dart/.

0
likes
160
points
198
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Cross-language Apache Fory runtime for Dart with generated serializers, schema evolution, and custom type support.

Homepage
Repository (GitHub)
View/report issues
Contributing

License

Apache-2.0 (license)

Dependencies

analyzer, build, build_config, meta, source_gen

More

Packages that depend on fory