Apache.Fory 1.0.0

dotnet add package Apache.Fory --version 1.0.0
                    
NuGet\Install-Package Apache.Fory -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Apache.Fory" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Apache.Fory" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Apache.Fory" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Apache.Fory --version 1.0.0
                    
#r "nuget: Apache.Fory, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Apache.Fory@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Apache.Fory&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Apache.Fory&version=1.0.0
                    
Install as a Cake Tool

Apache Fory™ C#

License

Apache Fory™ is a blazing fast multi-language serialization framework powered by JIT compilation and zero-copy techniques.

The C# implementation provides high-performance object graph serialization for .NET with source-generated serializers, optional reference tracking, schema evolution support, and cross-language compatibility.

Why Apache Fory™ C#?

  • High-performance binary serialization for .NET 8+
  • Cross-language compatibility with Java, Python, C++, Go, Rust, and JavaScript
  • Source-generator-based serializers for [ForyObject] types
  • Field-level schema descriptors with [ForyField(Type = typeof(...))]
  • Optional shared/circular reference tracking (TrackRef(true))
  • Compatible mode for schema evolution
  • Reduced-precision carriers for Half / BFloat16 scalars and Half[] / List<Half> / BFloat16[] / List<BFloat16> array payloads
  • Thread-safe runtime wrapper (ThreadSafeFory) for concurrent workloads
  • Dynamic object serialization APIs for heterogeneous payloads

Quick Start

Requirements

  • .NET SDK 8.0+
  • C# 12+

Add Apache Fory™ C#

From NuGet, reference the single Apache.Fory package. It includes the runtime plus the source generator for [ForyObject] types.

<ItemGroup>
  <PackageReference Include="Apache.Fory" Version="1.0.0" />
</ItemGroup>

For local development against this repository, reference the runtime project and generator project directly:

<ItemGroup>
  <ProjectReference Include="../fory/csharp/src/Fory/Fory.csproj" />
  <ProjectReference
      Include="../fory/csharp/src/Fory.Generator/Fory.Generator.csproj"
      OutputItemType="Analyzer"
      ReferenceOutputAssembly="false" />
</ItemGroup>

Basic Example

using Apache.Fory;

[ForyObject]
public sealed class User
{
    public long Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string? Email { get; set; }
}

Fory fory = Fory.Builder().Build();
fory.Register<User>(1);

User user = new()
{
    Id = 1,
    Name = "Alice",
    Email = "alice@example.com",
};

byte[] payload = fory.Serialize(user);
User decoded = fory.Deserialize<User>(payload);

Core Features

1. Object Graph Serialization

[ForyObject] types are serialized with generated serializers.

[ForyObject]
public sealed class Address
{
    public string Street { get; set; } = string.Empty;
    public int Zip { get; set; }
}

[ForyObject]
public sealed class Person
{
    public long Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public List<Address> Addresses { get; set; } = [];
}

Fory fory = Fory.Builder().Build();
fory.Register<Address>(100);
fory.Register<Person>(101);

2. Shared and Circular References

Enable reference tracking to preserve object identity.

[ForyObject]
public sealed class Node
{
    public int Value { get; set; }
    public Node? Next { get; set; }
}

Fory fory = Fory.Builder().TrackRef(true).Build();
fory.Register<Node>(200);

Node node = new() { Value = 7 };
node.Next = node;

Node decoded = fory.Deserialize<Node>(fory.Serialize(node));
System.Diagnostics.Debug.Assert(object.ReferenceEquals(decoded, decoded.Next));

3. Schema Evolution

Compatible mode allows schema changes between writer and reader.

[ForyObject]
public sealed class OneField
{
    public string? F1 { get; set; }
}

[ForyObject]
public sealed class TwoFields
{
    public string F1 { get; set; } = string.Empty;
    public string F2 { get; set; } = string.Empty;
}

Fory fory1 = Fory.Builder().Compatible(true).Build();
fory1.Register<OneField>(300);

Fory fory2 = Fory.Builder().Compatible(true).Build();
fory2.Register<TwoFields>(300);

TwoFields decoded = fory2.Deserialize<TwoFields>(fory1.Serialize(new OneField { F1 = "hello" }));

4. Dynamic Object Serialization

Use dynamic APIs for unknown/heterogeneous payloads.

Fory fory = Fory.Builder().Build();

Dictionary<object, object?> map = new()
{
    ["k1"] = 7,
    [2] = "v2",
    [true] = null,
};

byte[] payload = fory.Serialize<object?>(map);
object? decoded = fory.Deserialize<object?>(payload);

5. Thread-Safe Runtime

Fory is single-thread optimized. Use ThreadSafeFory for concurrent access.

using ThreadSafeFory fory = Fory.Builder().BuildThreadSafe();

fory.Register<User>(1);
Parallel.For(0, 128, i =>
{
    byte[] payload = fory.Serialize(i);
    int decoded = fory.Deserialize<int>(payload);
});

6. Custom Serializers

Provide custom encoding logic with Serializer<T>.

public sealed class PointSerializer : Serializer<Point>
{
    public override Point DefaultValue => new();

    public override void WriteData(WriteContext context, in Point value, bool hasGenerics)
    {
        context.Writer.WriteVarInt32(value.X);
        context.Writer.WriteVarInt32(value.Y);
    }

    public override Point ReadData(ReadContext context)
    {
        return new Point
        {
            X = context.Reader.ReadVarInt32(),
            Y = context.Reader.ReadVarInt32(),
        };
    }
}

Fory fory = Fory.Builder().Build();
fory.Register<Point, PointSerializer>(400);

Cross-Language Serialization

Use consistent registration mappings across languages.

Fory fory = Fory.Builder()
    .Compatible(true)
    .Build();

fory.Register<Person>(100); // same ID on other language peers

See xlang guide for mapping details.

Documentation

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 35 5/21/2026
1.0.0-rc1 77 5/18/2026
0.17.0 126 4/19/2026
0.16.0 124 3/17/2026