Skip to main content

Nino by Jason Xu

NuGet / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: Nino

High performance and low size binary serialization solution, especially for Unity.

Author: Jason Xu

NuGet: https://www.nuget.org/packages/Nino/

You can find more details at https://github.com/JasonXuDeveloper/Nino

Source: https://github.com/JasonXuDeveloper/Nino

Author

note

Jason Xu Alt text

Original Readme

note

Nino

Ultimate high-performance binary serialization library for C#

Build Status License NuGet OpenUPM

🌐 Official Website📚 Documentation🚀 Performance🇨🇳 中文

Fast, flexible, and effortless C# binary serialization


✨ Why Choose Nino?

🔧 Seamless Integration

Leverages C# Source Generators for automatic compile-time code generation. Zero manual setup required.

⚡ Blazing Performance

Engineered for high-throughput, low-latency scenarios with minimal GC pressure and memory allocation.

🎮 Unity Compatible

Works seamlessly with Unity projects and native Unity data types like Vector3 and Quaternion.

🛠️ Advanced Features

Handles complex scenarios like polymorphism, versioning, custom constructors, and private member serialization.


🎯 Core Features

🚀 Performance & Reliability

  • High-Speed Serialization: Consistently ranks among the fastest C# binary serializers
  • Low Memory Footprint: Minimal GC pressure and memory allocation
  • By-Reference Deserialization: Deserialize directly into existing objects to eliminate allocation overhead
  • Thread-Safe Operations: Fully concurrent serialization/deserialization without external locking
  • Data Integrity: Built-in type checking ensures data consistency

🧩 Comprehensive Type Support

  • Primitives & Built-ins: Full support for all C# primitive types (int, float, DateTime, etc.)
  • Modern C# Features: records, record structs, structs, classes, and generics
  • Collections: Any IEnumerable<T> including List<T>, Dictionary<TKey,TValue>, HashSet<T>, ConcurrentDictionary<TKey,TValue>
  • Advanced Generics: Complex nested types like Dictionary<string, List<CustomType[]>>
  • Value Types: ValueTuple, Tuple, KeyValuePair<TKey,TValue>, Nullable<T>

🎮 Unity & Cross-Platform

  • Unity Native Types: Vector3, Quaternion, Matrix4x4, and other Unity-specific data types
  • Cross-Assembly Support: Serialize types across different .NET assemblies and projects
  • Platform Agnostic: Works seamlessly across different .NET implementations

⚙️ Advanced Control

  • Polymorphism: Interface and abstract class serialization with type preservation
  • Custom Constructors: [NinoConstructor] for immutable types and factory patterns
  • Versioning & Migration: [NinoMember] ordering and [NinoFormerName] for backward compatibility
  • Privacy Control: [NinoType(true)] to include private/protected members
  • Selective Serialization: [NinoIgnore] to exclude specific fields
  • String Optimization: [NinoUtf8] for efficient UTF-8 string handling

📖 Quick Start

Installation

Standard .NET Projects:

dotnet add package Nino

Unity Projects (via OpenUPM):

openupm add com.jasonxudeveloper.nino

Basic Usage

[NinoType]
public class GameData
{
public int Score;
public string PlayerName;
public DateTime LastPlayed;
}

// Serialize
var data = new GameData \{ Score = 1000, PlayerName = "Player1", LastPlayed = DateTime.Now };
byte[] bytes = NinoSerializer.Serialize(data);

// Deserialize
var restored = NinoDeserializer.Deserialize<GameData>(bytes);

📚 Full Documentation →


📊 Performance

Nino consistently delivers exceptional performance across various scenarios. See detailed benchmarks and comparisons with other popular serialization libraries.

🚀 View Benchmarks →


🤝 Community & Support


Made with ❤️ by JasonXuDeveloper

Licensed under MIT License

About

note

binary serialization

How to use

Example (source csproj, source files)

This is the CSharp Project that references Nino

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nino" Version="4.0.0-beta.15" />
<PackageReference Include="Nino.Serialization" Version="4.0.0-beta.15" />
</ItemGroup>
</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <auto-generated/>
#pragma warning disable CS8669

using System;
using global::Nino.Core;
using System.Buffers;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace Serializer.NinoGen
{
public static partial class Deserializer
{
#region System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>> - Generated by transformer TrivialEnumerableUsingAdd
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(ReadOnlySpan<byte> data, out System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>> value)
{
var reader = new Reader(data);
Deserialize(out value, ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(out System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>> value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif

if (!reader.ReadCollectionHeader(out var length))
{
value = default;
return;
}

#if WEAK_VERSION_TOLERANCE
Reader eleReader;
#endif

var lst = new System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, object?>>();
for (int i = 0; i < length; i++)
{
#if WEAK_VERSION_TOLERANCE
eleReader = reader.Slice();
NinoDeserializer.Deserialize(out System.Collections.Generic.KeyValuePair<string, object?> item, ref eleReader);
#else
NinoDeserializer.Deserialize(out System.Collections.Generic.KeyValuePair<string, object?> item, ref reader);
#endif
lst.Add(item);
}

value = lst;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeserializeRef(ref System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>> value, ref Reader reader) => Deserialize(out value, ref reader);

#endregion

#region System.Collections.Generic.KeyValuePair<string, object?> - Generated by transformer KeyValuePair
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(ReadOnlySpan<byte> data, out System.Collections.Generic.KeyValuePair<string, object?> value)
{
var reader = new Reader(data);
Deserialize(out value, ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(out System.Collections.Generic.KeyValuePair<string, object?> value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
NinoDeserializer.Deserialize(out string k, ref reader);
object v = NinoDeserializer.DeserializeBoxed(ref reader, null);
value = new System.Collections.Generic.KeyValuePair<string, object?>(k, v);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeserializeRef(ref System.Collections.Generic.KeyValuePair<string, object?> value, ref Reader reader)
=> Deserialize(out value, ref reader);

#endregion

#region byte[] - Generated by transformer Array
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(ReadOnlySpan<byte> data, out byte[] value)
{
var reader = new Reader(data);
Deserialize(out value, ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(out byte[] value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
reader.Read(out value);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeserializeRef(ref byte[] value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
reader.ReadRef(ref value);
}

#endregion

#region int[] - Generated by transformer Array
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(ReadOnlySpan<byte> data, out int[] value)
{
var reader = new Reader(data);
Deserialize(out value, ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(out int[] value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
reader.Read(out value);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeserializeRef(ref int[] value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
reader.ReadRef(ref value);
}

#endregion

#region long? - Generated by transformer Nullable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(ReadOnlySpan<byte> data, out long? value)
{
var reader = new Reader(data);
Deserialize(out value, ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Deserialize(out long? value, ref Reader reader)
{
#if WEAK_VERSION_TOLERANCE
if (reader.Eof)
{
value = default;
return;
}
#endif
reader.Read(out bool hasValue);
if (!hasValue)
{
value = default;
return;
}

reader.UnsafeRead(out long ret);
value = ret;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeserializeRef(ref long? value, ref Reader reader) => Deserialize(out value, ref reader);

#endregion

}
}

Useful

Download Example (.NET C#)

Share Nino

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Nino

aaa

Category "Serializer" has the following generators:

1 GenPack

2 jsonConverterSourceGenerator

3 JsonPolymorphicGenerator

4 Nino

5 ProtobufSourceGenerator

6 Schema

7 StackXML

8 System.Text.Json

See category

Serializer