This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 90a45dd7f docs(dart): add dart docs (#3560)
90a45dd7f is described below

commit 90a45dd7f967ca9dabc6e6a9252d7ef6dad6725b
Author: Shawn Yang <[email protected]>
AuthorDate: Mon Apr 13 16:50:01 2026 +0800

    docs(dart): add dart docs (#3560)
    
    ## Why?
    
    
    
    ## What does this PR do?
    
    add dart docs
    
    ## Related issues
    
    
    
    ## AI Contribution Checklist
    
    
    
    - [ ] Substantial AI assistance was used in this PR: `yes` / `no`
    - [ ] If `yes`, I included a completed [AI Contribution
    
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
    in this PR description and the required `AI Usage Disclosure`.
    - [ ] If `yes`, my PR description includes the required `ai_review`
    summary and screenshot evidence of the final clean AI review results
    from both fresh reviewers on the current PR diff or current HEAD after
    the latest code changes.
    
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 dart/README.md                                     |  76 ------
 .../test/compatible_struct_slots_test.dart         |   2 +-
 .../test/cross_lang_test/xlang_test_main.dart      |   6 +-
 .../fory-test/test/generated_round_trip_test.dart  |   2 +-
 dart/packages/fory/CHANGELOG.md                    |   2 +-
 dart/packages/fory/README.md                       | 257 +++++++++++++++++----
 dart/packages/fory/lib/src/fory.dart               |  17 +-
 .../fory/test/manual_registration_test.dart        |  19 +-
 docs/guide/dart/_category_.json                    |   6 +
 docs/guide/dart/basic-serialization.md             | 142 ++++++++++++
 docs/guide/dart/code-generation.md                 | 120 ++++++++++
 docs/guide/dart/configuration.md                   | 110 +++++++++
 docs/guide/dart/cross-language.md                  | 187 +++++++++++++++
 docs/guide/dart/custom-serializers.md              | 156 +++++++++++++
 docs/guide/dart/field-configuration.md             | 136 +++++++++++
 docs/guide/dart/index.md                           | 143 ++++++++++++
 docs/guide/dart/schema-evolution.md                |  90 ++++++++
 docs/guide/dart/supported-types.md                 | 122 ++++++++++
 docs/guide/dart/troubleshooting.md                 | 105 +++++++++
 docs/guide/dart/type-registration.md               |  96 ++++++++
 20 files changed, 1666 insertions(+), 128 deletions(-)

diff --git a/dart/README.md b/dart/README.md
index 2c15e8b14..ee2cc6d66 100644
--- a/dart/README.md
+++ b/dart/README.md
@@ -143,79 +143,3 @@ The test suite is inspired by Apache Fory™ Java's testing 
approach and include
 - **Buffer Tests**: Validates correct memory handling for primitive types
 - **Cross-Language Tests**: Tests functionality against other Apache Fory™ 
implementations
 - **Performance Tests**: Simple benchmarks for serialization/deserialization 
performance
-
-### Running Tests
-
-Tests use the standard [dart test](https://pub.dev/packages/test) framework.
-
-To run tests:
-
-```bash
-# First, generate necessary code
-cd fory-test
-dart run build_runner build
-
-# Run all tests
-dart test
-
-# For more options (skipping tests, platform-specific tests, etc.)
-# See: https://github.com/dart-lang/test/blob/master/pkgs/test/README.md
-```
-
-#### Additional Configuration
-
-Inside the `fory-test/test_config` directory you will find YAML configuration 
files required by certain tests (for example, the `cross_language` tests).
-Before executing those tests, please review and adjust the configs in 
`fory-test/test_config` (or provide your own) so that they match your 
environment.
-
-## Code Quality
-
-Apache Fory™ Dart maintains high code quality standards. You can verify this 
using:
-
-```bash
-dart analyze
-dart fix --dry-run
-dart fix --apply
-```
-
-## Current Limitations
-
-- Only supports XLANG mode (priority was given to cross-language compatibility)
-- No out-of-band buffer functionality
-- No data type compression (e.g., String compression)
-- Generic parameters in user-defined types can be serialized but require 
manual type conversion after deserialization
-
-## Development Information
-
-- **Dart SDK**: 3.6.1
-
-## Dependencies
-
-### fory package:
-
-```
-analyzer: '>=6.5.0 <8.0.0'
-build: ^2.4.1
-build_config: ^1.1.0
-collection: ^1.19.1
-meta: ^1.14.0
-source_gen: ^2.0.0
-glob: ^2.1.3
-decimal: ^3.2.1
-lints: ^5.0.0
-build_runner: ^2.4.6
-```
-
-### fory-test package:
-
-```
-path: ^1.9.1
-yaml: ^3.1.3
-lints: ^5.0.0
-build: ^2.4.2
-build_runner: ^2.4.15
-test: ^1.24.0
-checks: ^0.3.0
-build_test: ^2.2.3
-analyzer: '>=6.5.0 <8.0.0'
-collection: ^1.19.1
-```
diff --git a/dart/packages/fory-test/test/compatible_struct_slots_test.dart 
b/dart/packages/fory-test/test/compatible_struct_slots_test.dart
index 76a19c8c9..a86c0f0e1 100644
--- a/dart/packages/fory-test/test/compatible_struct_slots_test.dart
+++ b/dart/packages/fory-test/test/compatible_struct_slots_test.dart
@@ -4,7 +4,7 @@ import 'package:test/test.dart';
 
 void main() {
   test('compatible named struct round trip scopes nested struct slots', () {
-    final fory = Fory(config: const Config(compatible: true));
+    final fory = Fory(compatible: true);
     registerXlangType(
       fory,
       Color,
diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart 
b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
index d766c6473..184f1f2da 100644
--- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
+++ b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart
@@ -41,10 +41,8 @@ void _writeFile(Uint8List bytes) {
 
 Fory _newFory({bool compatible = false}) {
   return Fory(
-    config: Config(
-      compatible: compatible,
-      checkStructVersion: !compatible,
-    ),
+    compatible: compatible,
+    checkStructVersion: !compatible,
   );
 }
 
diff --git a/dart/packages/fory-test/test/generated_round_trip_test.dart 
b/dart/packages/fory-test/test/generated_round_trip_test.dart
index 37f5bca3a..2acdc8ea4 100644
--- a/dart/packages/fory-test/test/generated_round_trip_test.dart
+++ b/dart/packages/fory-test/test/generated_round_trip_test.dart
@@ -84,7 +84,7 @@ void main() {
 
     test('fixed payload stays smaller than evolving payload in compatible 
mode',
         () {
-      final fory = Fory(config: const Config(compatible: true));
+      final fory = Fory(compatible: true);
       PersonFory.register(
         fory,
         EvolvingPayload,
diff --git a/dart/packages/fory/CHANGELOG.md b/dart/packages/fory/CHANGELOG.md
index b3312a256..c2fd74d72 100644
--- a/dart/packages/fory/CHANGELOG.md
+++ b/dart/packages/fory/CHANGELOG.md
@@ -1,3 +1,3 @@
 ## 0.17.0-dev
 
-- Rewrite the Dart runtime around `Fory`, `Buffer`, `WriteContext`, 
`ReadContext`, and `TypeResolver`.
+- Dart runtime implementation around `Fory`, `Buffer`, `WriteContext`, 
`ReadContext`, and `TypeResolver`.
diff --git a/dart/packages/fory/README.md b/dart/packages/fory/README.md
index 75eca69c0..417820b4a 100644
--- a/dart/packages/fory/README.md
+++ b/dart/packages/fory/README.md
@@ -1,17 +1,213 @@
 # Apache Fory Dart
 
-This package provides the Dart runtime for Apache Fory xlang serialization.
+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.
 
-For normal application code, use annotated objects plus the generated
-library-level namespace such as `ExampleFory.register(fory, Person, id: 1)` or
-`ExampleFory.register(fory, Person, namespace: 'example', typeName: 'Person')`.
-Those generated helpers keep serializer metadata private to the source library
-and register directly through generated serializer metadata, while manual
-`Serializer` implementations
-remain the advanced escape hatch for external types, custom wire behavior, or
-manual union implementations through `Fory.registerSerializer(...)`.
+## Features
 
-The runtime is built around a small public surface:
+- Cross-language serialization with the Fory xlang format
+- 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 xlang value wrappers such as `Int32`, `UInt32`, `Float16`,
+  `Float32`, `LocalDate`, and `Timestamp`
+
+## Getting Started
+
+Add `fory` to your package dependencies.
+
+```yaml
+dependencies:
+  fory: ^0.17.0-dev
+
+dev_dependencies:
+  build_runner: ^2.4.13
+```
+
+## Basic Usage
+
+Use `@ForyStruct()` for generated struct serializers and include the generated
+part file.
+
+```dart
+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:
+
+```bash
+dart run build_runner build --delete-conflicting-outputs
+```
+
+## Type Registration
+
+Generated types register through the generated library namespace.
+
+```dart
+PersonFory.register(fory, Person, id: 100);
+```
+
+Or use namespace and type name registration:
+
+```dart
+PersonFory.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
+
+Configure the runtime through `Config`.
+
+```dart
+final fory = Fory(
+  compatible: true,
+  maxDepth: 256,
+  maxCollectionSize: 1 << 20,
+  maxBinarySize: 64 * 1024 * 1024,
+);
+```
+
+Key options:
+
+- `compatible`: enables compatible struct encoding and decoding
+- `checkStructVersion`: enables struct-version validation in
+  schema-consistent mode
+- `maxDepth`: limits nesting depth for one operation
+- `maxCollectionSize`: limits collection and map payload sizes
+- `maxBinarySize`: limits 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.
+
+```dart
+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:
+
+```dart
+@ForyStruct()
+class NodeList {
+  NodeList();
+
+  @ForyField(ref: true)
+  List<Object?> values = <Object?>[];
+}
+```
+
+## Customized Serializers
+
+Use `Serializer<T>` when a type cannot use generated struct support or when you
+need custom wire behavior.
+
+```dart
+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.writeInt64(value.age);
+  }
+
+  @override
+  Person read(ReadContext context) {
+    final buffer = context.buffer;
+    return Person(buffer.readUtf8(), buffer.readInt64());
+  }
+}
+
+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);
+}
+```
+
+## Public API
+
+The main exported API includes:
 
 - `Fory`
 - `Config`
@@ -19,37 +215,20 @@ The runtime is built around a small public surface:
 - `WriteContext`
 - `ReadContext`
 - `Serializer`
+- `UnionSerializer`
 - `ForyStruct`
 - `ForyField`
+- Numeric and temporal wrappers such as `Int8`, `Int16`, `Int32`, `UInt8`,
+  `UInt16`, `UInt32`, `Float16`, `Float32`, `LocalDate`, and `Timestamp`
 
-Generated structs and enums register through the generated library namespace.
-Generated wrappers require an explicit registration mode: pass `id` for
-id-based registration, or pass both `namespace` and `typeName` for name-based
-registration.
-
-## Public API
-
-- `Fory`: root facade for xlang serialization, deserialization, generated type 
registration, and advanced manual serializer registration.
-- `Config`: immutable runtime options for compatible mode and safety limits.
-- `Buffer`: reusable byte buffer with explicit reader and writer indices.
-- `WriteContext` and `ReadContext`: advanced context APIs used by generated 
and manual serializers.
-- `Serializer`: low-level extension point for manual serializers and generated 
code.
-- `ForyStruct` and `ForyField`: annotations for struct code generation.
-- Numeric wrapper and time types such as `Int32`, `UInt32`, `Float16`, 
`LocalDate`, and `Timestamp`: xlang value types when Dart primitives are not 
precise enough to describe the wire type.
-
-Refer to the Dart doc comments on each exported symbol for the precise 
contract of each type and method.
-
-## Example
-
-The primary example uses generated serializers:
-
-1. Generate the example companion file:
-   `dart run build_runner build --delete-conflicting-outputs`
-2. Run the example:
-   `dart run example/example.dart`
+## Cross-Language Notes
 
-The example library exposes `ExampleFory.register(...)` for generated
-registration, for example `ExampleFory.register(fory, Person, namespace:
-'example', typeName: 'Person')`.
+- 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 wrappers or numeric field annotations when the exact xlang wire type
+  matters.
 
-The advanced manual serializer example lives at 
`example/manual_serializer.dart`.
+For the xlang wire format and type mapping details, see the Apache Fory
+specification in the main repository.
diff --git a/dart/packages/fory/lib/src/fory.dart 
b/dart/packages/fory/lib/src/fory.dart
index 86eda82a3..33a48587a 100644
--- a/dart/packages/fory/lib/src/fory.dart
+++ b/dart/packages/fory/lib/src/fory.dart
@@ -28,11 +28,24 @@ final class Fory {
   late final ReadContext _readContext;
   late final TypeResolver _typeResolver;
 
-  /// Creates a runtime configured by [config].
+  /// Creates a runtime configured by direct constructor options.
   ///
   /// The same instance can be reused across many operations. Each operation
   /// resets its transient read/write state before work starts.
-  Fory({Config config = const Config()}) {
+  Fory({
+    bool compatible = false,
+    bool checkStructVersion = true,
+    int maxDepth = Config.defaultMaxDepth,
+    int maxCollectionSize = Config.defaultMaxCollectionSize,
+    int maxBinarySize = Config.defaultMaxBinarySize,
+  }) {
+    final config = Config(
+      compatible: compatible,
+      checkStructVersion: checkStructVersion,
+      maxDepth: maxDepth,
+      maxCollectionSize: maxCollectionSize,
+      maxBinarySize: maxBinarySize,
+    );
     _buffer = Buffer();
     _typeResolver = TypeResolver(config);
     _writeContext = WriteContext(
diff --git a/dart/packages/fory/test/manual_registration_test.dart 
b/dart/packages/fory/test/manual_registration_test.dart
index 69fadde4d..b3e378b9f 100644
--- a/dart/packages/fory/test/manual_registration_test.dart
+++ b/dart/packages/fory/test/manual_registration_test.dart
@@ -134,7 +134,8 @@ void main() {
     expect(identical(roundTrip.first, roundTrip.second), isFalse);
   });
 
-  test('writeRefValueFlag returns true only when payload bytes must follow', 
() {
+  test('writeRefValueFlag returns true only when payload bytes must follow',
+      () {
     final fory = Fory();
     fory.registerSerializer(
       RefPayload,
@@ -159,12 +160,22 @@ void main() {
   test('root trackRef supports repeated strings', () {
     final fory = Fory();
     final shared = String.fromCharCodes('shared'.codeUnits);
-    final roundTrip =
-        fory.deserialize<Object?>(fory.serialize(<Object?>[shared, shared], 
trackRef: true))
-            as List;
+    final roundTrip = fory.deserialize<Object?>(
+        fory.serialize(<Object?>[shared, shared], trackRef: true)) as List;
 
     expect(roundTrip[0], equals('shared'));
     expect(roundTrip[1], equals('shared'));
     expect(identical(roundTrip[0], roundTrip[1]), isTrue);
   });
+
+  test('constructor forwards direct config parameters', () {
+    final fory = Fory(
+      compatible: true,
+      maxDepth: 64,
+      maxCollectionSize: 1024,
+      maxBinarySize: 4096,
+    );
+    final bytes = fory.serialize(Int32(42));
+    expect(fory.deserialize<Int32>(bytes), equals(Int32(42)));
+  });
 }
diff --git a/docs/guide/dart/_category_.json b/docs/guide/dart/_category_.json
new file mode 100644
index 000000000..47b8891a2
--- /dev/null
+++ b/docs/guide/dart/_category_.json
@@ -0,0 +1,6 @@
+{
+  "label": "Dart",
+  "position": 11,
+  "collapsible": true,
+  "collapsed": true
+}
diff --git a/docs/guide/dart/basic-serialization.md 
b/docs/guide/dart/basic-serialization.md
new file mode 100644
index 000000000..e7fa79d95
--- /dev/null
+++ b/docs/guide/dart/basic-serialization.md
@@ -0,0 +1,142 @@
+---
+title: Basic Serialization
+sidebar_position: 2
+id: dart_basic_serialization
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page covers the root serialization APIs in Apache Fory™ Dart.
+
+## Create and Reuse `Fory`
+
+```dart
+import 'package:fory/fory.dart';
+
+final fory = Fory();
+```
+
+Reuse the same runtime instance across calls. `Fory` owns the reusable 
`Buffer`, `WriteContext`, `ReadContext`, and `TypeResolver` services for that 
runtime.
+
+## Serialize and Deserialize Annotated Types
+
+```dart
+import 'package:fory/fory.dart';
+
+part 'person.fory.dart';
+
+@ForyStruct()
+class Person {
+  Person();
+
+  String name = '';
+  Int32 age = Int32(0);
+}
+
+void main() {
+  final fory = Fory();
+  PersonFory.register(
+    fory,
+    Person,
+    namespace: 'example',
+    typeName: 'Person',
+  );
+
+  final person = Person()
+    ..name = 'Ada'
+    ..age = Int32(36);
+
+  final bytes = fory.serialize(person);
+  final roundTrip = fory.deserialize<Person>(bytes);
+  print(roundTrip.name);
+}
+```
+
+`deserialize<T>` uses the wire metadata first, then checks that the result is 
assignable to `T`.
+
+## Null Root Values
+
+The root xlang frame starts with a one-byte bitmap. A null root payload is 
encoded by the root header, so serializing `null` works directly:
+
+```dart
+final fory = Fory();
+final bytes = fory.serialize(null);
+final value = fory.deserialize<Object?>(bytes);
+```
+
+## Serialize Collections and Dynamic Payloads
+
+You can serialize collection values directly:
+
+```dart
+final fory = Fory();
+final bytes = fory.serialize(<Object?>[
+  'hello',
+  Int32(42),
+  true,
+]);
+final value = fory.deserialize<List<Object?>>(bytes);
+```
+
+For heterogeneous collections, deserialize to `Object?`, `List<Object?>`, 
`Map<Object?, Object?>`, or a generated struct type that matches the wire 
schema.
+
+## Root Reference Tracking
+
+Use `trackRef: true` only when the root value itself is a graph or container 
with repeated references and there is no field metadata to request reference 
tracking.
+
+```dart
+final fory = Fory();
+final shared = String.fromCharCodes('shared'.codeUnits);
+final bytes = fory.serialize(<Object?>[shared, shared], trackRef: true);
+final roundTrip = fory.deserialize<List<Object?>>(bytes);
+print(identical(roundTrip[0], roundTrip[1]));
+```
+
+Inside generated structs, prefer field-level reference metadata with 
`@ForyField(ref: true)`.
+
+## Buffer-Based APIs
+
+Use `serializeTo` and `deserializeFrom` when you want explicit `Buffer` reuse.
+
+```dart
+final fory = Fory();
+final buffer = Buffer();
+
+fory.serializeTo(Int32(42), buffer);
+final value = fory.deserializeFrom<Int32>(buffer);
+```
+
+`serializeTo` clears the target buffer before writing. `deserializeFrom` 
consumes bytes from the buffer's current reader position.
+
+## Generated Registration Before Use
+
+Generated and manual user-defined types must be registered before use.
+
+```dart
+PersonFory.register(
+  fory,
+  Person,
+  id: 100,
+);
+```
+
+See [Type Registration](type-registration.md) and [Code 
Generation](code-generation.md).
+
+## Related Topics
+
+- [Configuration](configuration.md)
+- [Type Registration](type-registration.md)
+- [Field Configuration](field-configuration.md)
diff --git a/docs/guide/dart/code-generation.md 
b/docs/guide/dart/code-generation.md
new file mode 100644
index 000000000..5a65135a9
--- /dev/null
+++ b/docs/guide/dart/code-generation.md
@@ -0,0 +1,120 @@
+---
+title: Code Generation
+sidebar_position: 3
+id: dart_code_generation
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Fory Dart uses source generation for structs and enums defined in your Dart 
libraries.
+
+## Annotate Struct Types
+
+Mark classes with `@ForyStruct()` and include the generated part file.
+
+```dart
+import 'package:fory/fory.dart';
+
+part 'models.fory.dart';
+
+@ForyStruct()
+class Address {
+  Address();
+
+  String city = '';
+  String street = '';
+}
+
+@ForyStruct()
+class User {
+  User();
+
+  String name = '';
+  Int32 age = Int32(0);
+  Address address = Address();
+}
+```
+
+Enums in the same library also participate in generated registration.
+
+## Run the Generator
+
+From `dart/packages/fory` or the package that depends on the generator:
+
+```bash
+dart run build_runner build --delete-conflicting-outputs
+```
+
+The builder emits a `.fory.dart` part file next to the source library.
+
+## Register Through the Generated Namespace
+
+Generated code exposes a library-level namespace that knows how to install 
generated metadata into `Fory`.
+
+```dart
+final fory = Fory();
+ModelsFory.register(fory, Address, id: 1);
+ModelsFory.register(fory, User, id: 2);
+```
+
+Or use named registration:
+
+```dart
+ModelsFory.register(
+  fory,
+  User,
+  namespace: 'example',
+  typeName: 'User',
+);
+```
+
+Exactly one registration mode is required:
+
+- `id: ...`
+- `namespace: ...` plus `typeName: ...`
+
+## Choosing `evolving`
+
+`@ForyStruct()` defaults to `evolving: true`.
+
+```dart
+@ForyStruct(evolving: true)
+class Event {
+  Event();
+
+  String name = '';
+}
+```
+
+Use `evolving: true` when you want compatible-mode field evolution. Use 
`evolving: false` for a fixed schema when you want schema-consistent behavior.
+
+## Generated Registration Design
+
+Generated registration keeps serializer metadata private to the defining 
library while exposing a public wrapper API. Applications should call the 
generated wrapper instead of private helper functions.
+
+## When to Use Customized Serializers Instead
+
+Use [Custom Serializers](custom-serializers.md) when:
+
+- the type is external and cannot be annotated
+- you need custom payload layout
+- you are implementing a union or extension type manually
+
+## Related Topics
+
+- [Type Registration](type-registration.md)
+- [Field Configuration](field-configuration.md)
+- [Schema Evolution](schema-evolution.md)
diff --git a/docs/guide/dart/configuration.md b/docs/guide/dart/configuration.md
new file mode 100644
index 000000000..a213cca77
--- /dev/null
+++ b/docs/guide/dart/configuration.md
@@ -0,0 +1,110 @@
+---
+title: Configuration
+sidebar_position: 1
+id: dart_configuration
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page covers `Config` options and default runtime values for Apache Fory™ 
Dart.
+
+## Create a Runtime
+
+```dart
+import 'package:fory/fory.dart';
+
+final fory = Fory(
+  compatible: true,
+  maxDepth: 512,
+  maxCollectionSize: 1 << 18,
+  maxBinarySize: 16 * 1024 * 1024,
+);
+```
+
+The same `Fory` instance should be reused across many operations. `Fory` 
resets operation-local read and write state for each root call.
+
+## Options
+
+### `compatible`
+
+Enables compatible struct encoding and decoding.
+
+```dart
+final fory = Fory(compatible: true);
+```
+
+In compatible mode, generated evolving structs exchange shared `TypeDef` 
metadata rather than relying on the schema-consistent struct hash checks used 
by fixed-schema mode.
+
+### `checkStructVersion`
+
+Controls struct schema-version validation in schema-consistent mode.
+
+```dart
+final fory = Fory(
+  compatible: false,
+  checkStructVersion: true,
+);
+```
+
+This option is forced to `false` whenever `compatible` is `true`.
+
+### `maxDepth`
+
+Maximum nesting depth accepted during one serialization or deserialization 
operation.
+
+```dart
+const config = Config(maxDepth: 128);
+```
+
+Use this to bound recursive payloads and fail fast on malformed or 
unexpectedly deep graphs.
+
+### `maxCollectionSize`
+
+Maximum number of entries accepted for a single collection or map payload.
+
+```dart
+const config = Config(maxCollectionSize: 100000);
+```
+
+### `maxBinarySize`
+
+Maximum number of bytes accepted for a single binary payload.
+
+```dart
+const config = Config(maxBinarySize: 8 * 1024 * 1024);
+```
+
+## Defaults
+
+`Config()` defaults to:
+
+- `compatible: false`
+- `checkStructVersion: true`
+- `maxDepth: 256`
+- `maxCollectionSize: 1 << 20`
+- `maxBinarySize: 64 * 1024 * 1024`
+
+## Cross-Language Notes
+
+- The Dart runtime always reads and writes xlang frames.
+- Match `compatible` mode across communicating services when you depend on 
schema evolution.
+- Registration choices still matter: use the same numeric IDs or the same 
`namespace + typeName` mapping across all runtimes.
+
+## Related Topics
+
+- [Basic Serialization](basic-serialization.md)
+- [Schema Evolution](schema-evolution.md)
+- [Cross-Language](cross-language.md)
diff --git a/docs/guide/dart/cross-language.md 
b/docs/guide/dart/cross-language.md
new file mode 100644
index 000000000..2c700865b
--- /dev/null
+++ b/docs/guide/dart/cross-language.md
@@ -0,0 +1,187 @@
+---
+title: Cross-Language Serialization
+sidebar_position: 9
+id: dart_cross_language
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Apache Fory™ Dart supports cross-language serialization with other Fory 
runtimes.
+
+## Cross-Language Runtime
+
+The Dart runtime only supports xlang payloads, so you do not enable a separate 
cross-language mode.
+
+```dart
+final fory = Fory();
+```
+
+Configure only the runtime behavior that still varies, such as compatible mode 
and safety limits.
+
+## Use Stable Registration Identity
+
+Choose one registration strategy and keep it stable across all peers.
+
+### Numeric ID example
+
+```dart
+ModelsFory.register(fory, Person, id: 100);
+```
+
+### Name-based example
+
+```dart
+ModelsFory.register(
+  fory,
+  Person,
+  namespace: 'example',
+  typeName: 'Person',
+);
+```
+
+## Dart to Java Example
+
+### Dart
+
+```dart
+import 'package:fory/fory.dart';
+
+part 'person.fory.dart';
+
+@ForyStruct()
+class Person {
+  Person();
+
+  String name = '';
+  Int32 age = Int32(0);
+}
+
+final fory = Fory();
+PersonFory.register(fory, Person, id: 100);
+final bytes = fory.serialize(Person()
+  ..name = 'Alice'
+  ..age = Int32(30));
+```
+
+### Java
+
+```java
+Fory fory = Fory.builder()
+    .withLanguage(Language.XLANG)
+    .build();
+
+fory.register(Person.class, 100);
+Person value = (Person) fory.deserialize(bytesFromDart);
+```
+
+## Dart to C# Example
+
+### Dart
+
+```dart
+final fory = Fory(compatible: true);
+PersonFory.register(fory, Person, id: 100);
+final bytes = fory.serialize(Person()
+  ..name = 'Alice'
+  ..age = Int32(30));
+```
+
+### CSharp
+
+```csharp
+[ForyObject]
+public sealed class Person
+{
+    public string Name { get; set; } = string.Empty;
+    public int Age { get; set; }
+}
+
+Fory fory = Fory.Builder()
+    .Compatible(true)
+    .Build();
+
+fory.Register<Person>(100);
+Person person = fory.Deserialize<Person>(payloadFromDart);
+```
+
+## Dart to Go Example
+
+### Dart
+
+```dart
+final fory = Fory();
+PersonFory.register(fory, Person, id: 100);
+final bytes = fory.serialize(Person()
+  ..name = 'Alice'
+  ..age = Int32(30));
+```
+
+### Go
+
+```go
+type Person struct {
+    Name string
+    Age  int32
+}
+
+f := fory.New(fory.WithXlang(true))
+_ = f.RegisterStruct(Person{}, 100)
+
+var person Person
+_ = f.Deserialize(bytesFromDart, &person)
+```
+
+## Field Matching Rules
+
+The xlang spec is the source of truth, but for application authors the 
practical rules are:
+
+1. Register the same logical type identity on every side.
+2. Keep field meaning aligned across languages.
+3. For evolving schemas, keep field IDs stable.
+4. Use compatible type mappings for numeric widths, timestamps, collections, 
and nullability.
+5. Validate real payload round trips.
+
+Dart model fields often use lowerCamelCase. Go fields are exported PascalCase. 
C# commonly uses PascalCase properties. What matters is that the peer runtimes 
agree on the logical field mapping and wire schema. Stable field IDs are the 
safest option when models evolve independently.
+
+## Type Mapping Notes for Dart
+
+Because Dart `int` is not itself a promise about the exact xlang wire width, 
prefer wrappers or numeric field annotations when exact cross-language 
interpretation matters:
+
+- `Int32` for xlang `int32`
+- `UInt32` for xlang `uint32`
+- `Float16` and `Float32` for reduced-width floating point
+- `Timestamp` and `LocalDate` for explicit temporal semantics
+
+See [Supported Types](supported-types.md) and [xlang type 
mapping](../../specification/xlang_type_mapping.md).
+
+## Validation Advice
+
+Before relying on an interop contract, test the same payload through every 
runtime you support.
+
+At minimum for Dart runtime work:
+
+```bash
+cd dart
+dart run build_runner build --delete-conflicting-outputs
+dart analyze
+dart test
+```
+
+## Related Topics
+
+- [Type Registration](type-registration.md)
+- [Schema Evolution](schema-evolution.md)
+- [Cross-language guide](../xlang/index.md)
diff --git a/docs/guide/dart/custom-serializers.md 
b/docs/guide/dart/custom-serializers.md
new file mode 100644
index 000000000..91ddc6945
--- /dev/null
+++ b/docs/guide/dart/custom-serializers.md
@@ -0,0 +1,156 @@
+---
+title: Custom Serializers
+sidebar_position: 5
+id: dart_custom_serializers
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Use customized serializers when generated struct support is not the right fit.
+
+## When Customized Serializers Make Sense
+
+Typical cases include:
+
+- external types you cannot annotate
+- custom payload layouts
+- customized extension types
+- unions built on the `UnionSerializer<T>` base class
+
+## Implement `Serializer<T>`
+
+```dart
+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.writeInt64(value.age);
+  }
+
+  @override
+  Person read(ReadContext context) {
+    final buffer = context.buffer;
+    return Person(buffer.readUtf8(), buffer.readInt64());
+  }
+}
+```
+
+Register it before use:
+
+```dart
+final fory = Fory();
+fory.registerSerializer(
+  Person,
+  const PersonSerializer(),
+  namespace: 'example',
+  typeName: 'Person',
+);
+```
+
+## Use `WriteContext` and `ReadContext`
+
+Manual serializers should do nested xlang work through the context rather than 
calling root APIs recursively.
+
+### Write nested values with reference handling
+
+```dart
+@override
+void write(WriteContext context, Wrapper value) {
+  context.writeRef(value.child);
+}
+
+@override
+Wrapper read(ReadContext context) {
+  return Wrapper(context.readRef() as Child);
+}
+```
+
+### Write values without seeding references
+
+`writeNonRef` writes a non-reference payload and does not seed later 
back-references.
+
+```dart
+context.writeNonRef(value.child);
+```
+
+### Fine-grained ref/value control
+
+Use `writeRefValueFlag` when your serializer needs explicit control over 
whether payload bytes follow.
+
+```dart
+if (context.writeRefValueFlag(value.payload)) {
+  context.writeNonRef(value.payload);
+}
+```
+
+## Unions
+
+Manual union serializers should extend `UnionSerializer<T>`.
+
+```dart
+final class ShapeSerializer extends UnionSerializer<Shape> {
+  const ShapeSerializer();
+
+  @override
+  void write(WriteContext context, Shape value) {
+    // write active alternative
+  }
+
+  @override
+  Shape read(ReadContext context) {
+    // read active alternative
+    throw UnimplementedError();
+  }
+}
+```
+
+The xlang spec defines `UNION`, `TYPED_UNION`, `NAMED_UNION`, and `NONE` wire 
types. Use registrations that match the peers you interoperate with.
+
+## Early Reference Binding During Reads
+
+If your serializer allocates an object before all nested fields are read, bind 
it early so back-references can resolve to that instance.
+
+```dart
+final value = Node.empty();
+context.reference(value);
+value.next = context.readRef() as Node?;
+return value;
+```
+
+## Best Practices
+
+- Keep payload code focused on the payload only.
+- Let `Fory` own the root frame and top-level reset lifecycle.
+- Prefer direct buffer access for repeated primitive IO inside hot serializers.
+- Register serializers consistently across all peers.
+
+## Related Topics
+
+- [Type Registration](type-registration.md)
+- [Cross-Language](cross-language.md)
+- [Troubleshooting](troubleshooting.md)
diff --git a/docs/guide/dart/field-configuration.md 
b/docs/guide/dart/field-configuration.md
new file mode 100644
index 000000000..8a9402de0
--- /dev/null
+++ b/docs/guide/dart/field-configuration.md
@@ -0,0 +1,136 @@
+---
+title: Field Configuration
+sidebar_position: 6
+id: dart_field_configuration
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Use `@ForyField(...)` to override generated serializer behavior for individual 
fields.
+
+## Options Overview
+
+```dart
+@ForyField(
+  skip: false,
+  id: 10,
+  nullable: true,
+  ref: true,
+  dynamic: false,
+)
+```
+
+## `skip`
+
+Exclude a field from generated serialization.
+
+```dart
+@ForyField(skip: true)
+String cachedDisplayName = '';
+```
+
+## `id`
+
+Provides a stable field identifier for compatible structs.
+
+```dart
+@ForyField(id: 1)
+String name = '';
+```
+
+In compatible mode, stable field IDs matter more than declaration order. Keep 
IDs fixed once payloads are shared.
+
+## `nullable`
+
+Overrides inferred nullability.
+
+```dart
+@ForyField(nullable: true)
+String nickname = '';
+```
+
+`null` means "use the Dart type as written." In cross-language scenarios, make 
sure your nullability contract also matches peer runtimes.
+
+## `ref`
+
+Enables reference tracking for that field.
+
+```dart
+@ForyField(ref: true)
+List<Object?> sharedNodes = <Object?>[];
+```
+
+Basic scalar values never track references even if `ref` is set to `true`.
+
+## `dynamic`
+
+Controls whether generated code writes runtime type metadata for the field.
+
+```dart
+@ForyField(dynamic: true)
+Object? payload;
+```
+
+- `null`: auto
+- `false`: use the declared field type
+- `true`: write runtime type information
+
+This is the key knob for polymorphic fields and heterogeneous object payloads.
+
+## Numeric Encoding Overrides
+
+Use numeric annotations to control the xlang wire type used for integer fields.
+
+```dart
+@ForyStruct()
+class Sample {
+  Sample();
+
+  @Int32Type(compress: false)
+  int fixedWidthInt = 0;
+
+  @Int64Type(encoding: LongEncoding.tagged)
+  int compactLong = 0;
+
+  @Uint32Type(compress: true)
+  int smallUnsigned = 0;
+}
+```
+
+Available numeric annotations include:
+
+- `@Int32Type(...)`
+- `@Int64Type(...)`
+- `@Uint8Type()`
+- `@Uint16Type()`
+- `@Uint32Type(...)`
+- `@Uint64Type(...)`
+
+These should be chosen to match the intended xlang wire type and peer-language 
expectations.
+
+## Field Alignment Across Languages
+
+Cross-language decoding depends on matching field names or stable field IDs. 
When models differ across languages:
+
+- keep equivalent logical fields aligned
+- prefer stable `id` values for evolving structs
+- use `dynamic: true` only when the field is genuinely polymorphic
+
+## Related Topics
+
+- [Code Generation](code-generation.md)
+- [Schema Evolution](schema-evolution.md)
+- [Cross-Language](cross-language.md)
diff --git a/docs/guide/dart/index.md b/docs/guide/dart/index.md
new file mode 100644
index 000000000..e52ef5f18
--- /dev/null
+++ b/docs/guide/dart/index.md
@@ -0,0 +1,143 @@
+---
+title: Dart Serialization Guide
+sidebar_position: 0
+id: dart_serialization_index
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Apache Fory™ Dart is a cross-language serialization runtime for Dart. It reads 
and writes the xlang wire format defined by the [xlang serialization 
specification](../../specification/xlang_serialization_spec.md) and is designed 
around generated serializers with an advanced customized serializer escape 
hatch.
+
+## Why Fory Dart?
+
+- Cross-language compatibility with other Fory xlang runtimes
+- Generated serializers for annotated Dart models
+- Compatible mode for schema evolution
+- Optional reference tracking for shared and circular object graphs
+- Manual serializer support for external types, custom wire behavior, and 
unions
+- A small public API centered on `Fory`, `Config`, annotations, and xlang 
value wrappers
+
+## Runtime Model
+
+The Dart runtime only supports xlang payloads. There is no separate 
native-mode builder. Root operations happen through `Fory`, while nested 
payload work stays in explicit `WriteContext` and `ReadContext` instances. This 
mirrors the ownership model described in the [xlang implementation 
guide](../../specification/xlang_implementation_guide.md).
+
+## Quick Start
+
+### Requirements
+
+- Dart SDK 3.6 or later
+- `build_runner` for generated serializers
+
+### Install
+
+Add the package from your Dart workspace or package source. In this 
repository, the runtime lives under `dart/packages/fory`.
+
+```yaml
+dependencies:
+  fory:
+    path: packages/fory
+
+dev_dependencies:
+  build_runner: ^2.4.0
+```
+
+### Basic Example
+
+```dart
+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:
+
+```bash
+cd dart/packages/fory
+dart run build_runner build --delete-conflicting-outputs
+```
+
+## Core API
+
+- `Fory({bool compatible = false, bool checkStructVersion = true, int maxDepth 
= Config.defaultMaxDepth, int maxCollectionSize = 
Config.defaultMaxCollectionSize, int maxBinarySize = 
Config.defaultMaxBinarySize})`
+- `serialize(Object? value, {bool trackRef = false})`
+- `deserialize<T>(Uint8List bytes)`
+- `register(Type type, {int? id, String? namespace, String? typeName})`
+- `registerSerializer(Type type, Serializer serializer, ...)`
+- `@ForyStruct()` and `@ForyField(...)` for generated serializers
+- xlang value wrappers such as `Int8`, `Int16`, `Int32`, `UInt8`, `UInt16`, 
`UInt32`, `Float16`, `Float32`, `LocalDate`, and `Timestamp`
+
+## Documentation
+
+| Topic                                         | Description                  
                                   |
+| --------------------------------------------- | 
--------------------------------------------------------------- |
+| [Configuration](configuration.md)             | Runtime options, compatible 
mode, and safety limits             |
+| [Basic Serialization](basic-serialization.md) | `serialize`, `deserialize`, 
generated registration, root graphs |
+| [Code Generation](code-generation.md)         | `@ForyStruct`, build runner, 
and generated namespaces           |
+| [Type Registration](type-registration.md)     | ID-based vs name-based 
registration and registration rules      |
+| [Custom Serializers](custom-serializers.md)   | Manual `Serializer<T>` 
implementations and unions               |
+| [Field Configuration](field-configuration.md) | `@ForyField`, field IDs, 
nullability, references, polymorphism  |
+| [Supported Types](supported-types.md)         | Built-in xlang values, 
wrappers, collections, and structs       |
+| [Schema Evolution](schema-evolution.md)       | Compatible structs and 
evolving schemas                         |
+| [Cross-Language](cross-language.md)           | Interoperability rules and 
field alignment                      |
+| [Troubleshooting](troubleshooting.md)         | Common errors, diagnostics, 
and validation steps                |
+
+## Related Resources
+
+- [Xlang serialization 
specification](../../specification/xlang_serialization_spec.md)
+- [Xlang implementation 
guide](../../specification/xlang_implementation_guide.md)
+- [Cross-language guide](../xlang/index.md)
+- [Dart runtime source 
directory](https://github.com/apache/fory/tree/main/dart)
diff --git a/docs/guide/dart/schema-evolution.md 
b/docs/guide/dart/schema-evolution.md
new file mode 100644
index 000000000..778c39bce
--- /dev/null
+++ b/docs/guide/dart/schema-evolution.md
@@ -0,0 +1,90 @@
+---
+title: Schema Evolution
+sidebar_position: 8
+id: dart_schema_evolution
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+Fory Dart supports schema evolution through compatible structs.
+
+## Two Struct Modes
+
+### Schema-Consistent Mode
+
+This is the default when `Config.compatible` is `false`.
+
+- Structs use the schema-consistent path.
+- `checkStructVersion` can validate schema-version compatibility.
+- This mode is appropriate when both sides evolve in lockstep or when you want 
stricter validation.
+
+### Compatible Mode
+
+Enable compatible mode when you want evolving field metadata on the wire.
+
+```dart
+final fory = Fory(compatible: true);
+```
+
+In compatible mode:
+
+- evolving structs use compatible struct encoding
+- `checkStructVersion` is disabled
+- field IDs become the stability anchor for changed schemas
+- TypeDef metadata is shared and reused across payloads
+
+## Generated Struct Controls
+
+`@ForyStruct(evolving: true)` is the default and is the right choice when the 
type may evolve over time.
+
+```dart
+@ForyStruct(evolving: true)
+class UserProfile {
+  UserProfile();
+
+  @ForyField(id: 1)
+  String name = '';
+
+  @ForyField(id: 2, nullable: true)
+  String? nickname;
+}
+```
+
+Use explicit stable field IDs when a schema may change.
+
+## Safe Evolution Practices
+
+Typical compatible changes include:
+
+- adding a new optional field with a new field ID
+- keeping existing field IDs stable
+- widening consumer behavior to tolerate missing data
+
+Changes that require extra care include:
+
+- reusing an old field ID for different semantics
+- changing a field's logical cross-language meaning
+- changing registration identity for an existing type
+
+## Cross-Language Guidance
+
+Schema evolution only works when all runtimes agree on the type registration 
identity and the logical meaning of field IDs. Validate rolling upgrades with 
real round trips across the languages you support.
+
+## Related Topics
+
+- [Configuration](configuration.md)
+- [Field Configuration](field-configuration.md)
+- [Cross-Language](cross-language.md)
diff --git a/docs/guide/dart/supported-types.md 
b/docs/guide/dart/supported-types.md
new file mode 100644
index 000000000..edf2f29f9
--- /dev/null
+++ b/docs/guide/dart/supported-types.md
@@ -0,0 +1,122 @@
+---
+title: Supported Types
+sidebar_position: 7
+id: dart_supported_types
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page summarizes the main xlang-facing types in Apache Fory Dart.
+
+## Primitive-Like Dart Values
+
+The runtime supports common Dart values directly where they map cleanly to 
xlang types:
+
+- `bool`
+- `int`
+- `double`
+- `String`
+- `Uint8List` and other supported typed byte containers
+- `List`, `Set`, and `Map`
+- `DateTime`-adjacent values through explicit wrappers such as `Timestamp` and 
`LocalDate`
+
+Because Dart `int` and `double` are broader runtime concepts than many xlang 
scalar types, wrapper types and field annotations are used when the exact wire 
type matters.
+
+## Integer Wrappers
+
+Use wrapper classes when you need an exact xlang fixed-width integer type.
+
+```dart
+final Int8 tiny = Int8(-1);
+final Int16 shortValue = Int16(7);
+final Int32 age = Int32(36);
+final UInt8 flags = UInt8(255);
+final UInt16 port = UInt16(65535);
+final UInt32 count = UInt32(4000000000);
+```
+
+Available wrappers:
+
+- `Int8`
+- `Int16`
+- `Int32`
+- `UInt8`
+- `UInt16`
+- `UInt32`
+
+Each wrapper normalizes the stored value to the target bit width.
+
+## Floating-Point Wrappers
+
+Use explicit wrapper types when you need a precise non-`float64` wire type.
+
+- `Float16`
+- `Float32`
+
+Dart `double` maps naturally to the xlang `float64` family.
+
+## Time and Date Types
+
+The runtime exposes explicit xlang-friendly temporal wrappers:
+
+- `Timestamp` for seconds-plus-nanoseconds UTC instants
+- `LocalDate` for timezone-free calendar dates
+
+```dart
+final timestamp = Timestamp.fromDateTime(DateTime.now().toUtc());
+final birthday = LocalDate(1990, 12, 1);
+```
+
+## Structs and Enums
+
+User-defined structs and enums are supported through generated registration or 
customized serializers.
+
+```dart
+@ForyStruct()
+class User {
+  User();
+
+  String name = '';
+  Int32 age = Int32(0);
+}
+```
+
+## Collections
+
+Fory Dart supports the core xlang collection shapes:
+
+- `List<T>`
+- `Set<T>`
+- `Map<K, V>`
+
+Cross-language compatibility still depends on element and key types having 
compatible peer-language mappings. Avoid mutable collection keys.
+
+## Typed Arrays and Binary Values
+
+The xlang spec defines dedicated wire types for binary payloads and numeric 
arrays. In Dart, use the typed values exported by the runtime and test the 
exact round trip you need with your peer languages.
+
+## Exact Mapping Rules
+
+For the complete cross-language mapping, see:
+
+- [Xlang type mapping](../../specification/xlang_type_mapping.md)
+- [Cross-Language](cross-language.md)
+
+## Related Topics
+
+- [Field Configuration](field-configuration.md)
+- [Cross-Language](cross-language.md)
+- [Schema Evolution](schema-evolution.md)
diff --git a/docs/guide/dart/troubleshooting.md 
b/docs/guide/dart/troubleshooting.md
new file mode 100644
index 000000000..1d9fd2fc2
--- /dev/null
+++ b/docs/guide/dart/troubleshooting.md
@@ -0,0 +1,105 @@
+---
+title: Troubleshooting
+sidebar_position: 10
+id: dart_troubleshooting
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page covers common Dart runtime issues and fixes.
+
+## `Only xlang payloads are supported by the Dart runtime.`
+
+The Dart runtime only deserializes xlang frames. Make sure the peer runtime is 
writing xlang payloads rather than a language-native format.
+
+- Java must use `withLanguage(Language.XLANG)`.
+- Go must enable `WithXlang(true)`.
+- Other peers must use their xlang-compatible path.
+
+## `Type ... is not registered.`
+
+Generated and manual user-defined types must be registered before reading or 
writing them.
+
+Checklist:
+
+1. Run code generation.
+2. Register the type through the generated namespace or `registerSerializer`.
+3. Register all nested user-defined types, not only the root type.
+
+## Generated part file is missing or stale
+
+Regenerate code:
+
+```bash
+cd dart/packages/fory
+dart run build_runner build --delete-conflicting-outputs
+```
+
+If you moved files or renamed types, rebuild before re-running analysis or 
tests.
+
+## `Deserialized value has type ..., expected ...`
+
+`deserialize<T>` validates the runtime result after decoding. This error 
usually means:
+
+- the payload describes a different root type than the requested `T`
+- registration points to a different logical type than expected
+- a dynamic payload should be decoded as `Object?` or a container type first
+
+## Unexpected reference identity behavior
+
+Check whether reference tracking is enabled in the correct place:
+
+- root graph or root container: `trackRef: true`
+- generated field graph: `@ForyField(ref: true)`
+- customized serializer: use `writeRef`, `readRef`, and 
`context.reference(...)` correctly
+
+`writeNonRef` intentionally does not seed later back-references.
+
+## Cross-language field mismatch
+
+Symptoms include missing data, default values, or type errors on peers.
+
+Check:
+
+- same registration identity on both sides
+- stable field IDs for evolving structs
+- matching logical field names and meanings
+- compatible numeric widths and temporal types
+
+## Validation Commands
+
+For the main Dart workspace:
+
+```bash
+cd dart
+dart run build_runner build --delete-conflicting-outputs
+dart analyze
+dart test
+```
+
+For the integration-style test package:
+
+```bash
+cd dart/packages/fory-test
+dart run build_runner build --delete-conflicting-outputs
+dart test
+```
+
+## Related Topics
+
+- [Cross-Language](cross-language.md)
+- [Code Generation](code-generation.md)
+- [Custom Serializers](custom-serializers.md)
diff --git a/docs/guide/dart/type-registration.md 
b/docs/guide/dart/type-registration.md
new file mode 100644
index 000000000..5d7456025
--- /dev/null
+++ b/docs/guide/dart/type-registration.md
@@ -0,0 +1,96 @@
+---
+title: Type Registration
+sidebar_position: 4
+id: dart_type_registration
+license: |
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+---
+
+This page covers how to register user-defined types in Apache Fory™ Dart.
+
+## Registration Modes
+
+Fory Dart supports the same two registration styles used by other xlang 
runtimes.
+
+### Register by Numeric ID
+
+Numeric IDs are compact on the wire and fast to resolve.
+
+```dart
+ModelsFory.register(fory, User, id: 100);
+```
+
+Use the same numeric ID for the same logical type in every language.
+
+### Register by Namespace and Type Name
+
+Name-based registration avoids global numeric ID coordination and is often 
easier across multiple teams.
+
+```dart
+ModelsFory.register(
+  fory,
+  User,
+  namespace: 'example',
+  typeName: 'User',
+);
+```
+
+The same `namespace + typeName` pair must be used by every runtime that reads 
or writes the type.
+
+## Generated Type Registration
+
+Generated types should normally be registered through the generated namespace 
wrapper:
+
+```dart
+UserModelsFory.register(fory, User, id: 100);
+```
+
+Internally, the wrapper installs generated metadata and then calls 
`Fory.register(...)`.
+
+## Register a Manual Serializer
+
+Customized serializers register through `registerSerializer`:
+
+```dart
+fory.registerSerializer(
+  ExternalType,
+  const ExternalTypeSerializer(),
+  namespace: 'example',
+  typeName: 'ExternalType',
+);
+```
+
+## Cross-Language Requirements
+
+Registration must match across runtimes:
+
+- same numeric ID, or
+- same namespace and type name
+
+The wire format distinguishes built-in xlang type IDs from user-registered 
type IDs. The user ID is encoded separately as an unsigned varint32, as 
described in the [xlang serialization 
specification](../../specification/xlang_serialization_spec.md).
+
+## Common Rules
+
+- Register before the first serialize or deserialize call.
+- Register nested user-defined types as well as root types.
+- Keep IDs stable once payloads are persisted or exchanged across services.
+- Do not mix a numeric ID on one side with a name-based registration on the 
other side for the same type.
+
+## Related Topics
+
+- [Code Generation](code-generation.md)
+- [Cross-Language](cross-language.md)
+- [Custom Serializers](custom-serializers.md)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to