title: Getting Started sidebar_position: 10 id: xlang_getting_started 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 guide covers installation and basic setup for cross-language serialization in all supported languages.

Installation

Java

Maven:

<dependency>
  <groupId>org.apache.fory</groupId>
  <artifactId>fory-core</artifactId>
  <version>0.14.1</version>
</dependency>

Gradle:

implementation 'org.apache.fory:fory-core:0.14.1'

Python

pip install pyfory

Go

go get github.com/apache/fory/go/fory

Rust

[dependencies]
fory = "0.13"

JavaScript

npm install @apache-fory/fory

C++

Use Bazel or CMake to build from source. See C++ Guide for details.

Enable Cross-Language Mode

Each language requires enabling xlang mode to ensure binary compatibility across languages.

Java

import org.apache.fory.*;
import org.apache.fory.config.*;

Fory fory = Fory.builder()
    .withLanguage(Language.XLANG)  // Enable cross-language mode
    .withRefTracking(true)          // Optional: for circular references
    .build();

Python

import pyfory

# xlang mode is enabled by default
fory = pyfory.Fory()

# Explicit configuration
fory = pyfory.Fory(ref_tracking=True)

Go

import forygo "github.com/apache/fory/go/fory"

fory := forygo.NewFory()
// Or with reference tracking
fory := forygo.NewFory(true)

Rust

use fory::Fory;

let fory = Fory::default();

JavaScript

import Fory from "@apache-fory/fory";

const fory = new Fory();

C++

#include "fory/serialization/fory.h"

using namespace fory::serialization;

auto fory = Fory::builder()
    .xlang(true)
    .build();

Type Registration

Custom types must be registered with consistent names or IDs across all languages.

Register by Name (Recommended)

Using string names is more flexible and less prone to conflicts:

Java:

fory.register(Person.class, "example.Person");

Python:

fory.register_type(Person, typename="example.Person")

Go:

fory.RegisterNamedType(Person{}, "example.Person")

Rust:

#[derive(Fory)]
#[tag("example.Person")]
struct Person {
    name: String,
    age: i32,
}

JavaScript:

const description = Type.object("example.Person", {
  name: Type.string(),
  age: Type.int32(),
});
fory.registerSerializer(description);

C++:

fory.register_struct<Person>("example.Person");
// For enums, use register_enum:
// fory.register_enum<Color>("example.Color");

Register by ID

Using numeric IDs is faster and produces smaller binary output:

Java:

fory.register(Person.class, 100);

Python:

fory.register_type(Person, type_id=100)

Go:

fory.Register(Person{}, 100)

C++:

fory.register_struct<Person>(100);
// For enums, use register_enum:
// fory.register_enum<Color>(101);

Hello World Example

A complete example showing serialization in Java and deserialization in Python:

Java (Serializer)

import org.apache.fory.*;
import org.apache.fory.config.*;
import java.nio.file.*;

public class Person {
    public String name;
    public int age;
}

public class HelloWorld {
    public static void main(String[] args) throws Exception {
        Fory fory = Fory.builder()
            .withLanguage(Language.XLANG)
            .build();
        fory.register(Person.class, "example.Person");

        Person person = new Person();
        person.name = "Alice";
        person.age = 30;

        byte[] bytes = fory.serialize(person);
        Files.write(Path.of("person.bin"), bytes);
        System.out.println("Serialized to person.bin");
    }
}

Python (Deserializer)

import pyfory
from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: pyfory.Int32Type

fory = pyfory.Fory()
fory.register_type(Person, typename="example.Person")

with open("person.bin", "rb") as f:
    data = f.read()

person = fory.deserialize(data)
print(f"Name: {person.name}, Age: {person.age}")
# Output: Name: Alice, Age: 30

Best Practices

  1. Use consistent type names: Ensure all languages use the same type name or ID
  2. Enable reference tracking: If your data has circular or shared references
  3. Reuse Fory instances: Creating Fory is expensive; reuse instances
  4. Use type annotations: In Python, use pyfory.Int32Type etc. for precise type mapping
  5. Test cross-language: Verify serialization works across all target languages

Next Steps