Skip to content
JasonXuDeveloperPublic

About

The fastest binary serializer for C#. Source-generated, zero-allocation: services, RPC, messaging, caching, storage, Unity and Godot.

Topics

Resources

Contributing

Stars

655 stars

Watchers

15 watching

Forks

Latest commit

 

History

2,444 Commits

Folders and files

Repository files navigation

Nino logo

Nino

The fastest binary serializer for C#.
Source-generated, zero-allocation, thread-safe and safe on untrusted input.
For .NET, Unity, Godot and HybridCLR, with the same bytes on every platform and runtime, Go, Rust and TypeScript included.

NuGet OpenUPM crates.io
npm Go
Build License Docs Ask DeepWiki

🌐 Website · 🚀 Getting Started · What's new in v4 · Benchmarks · 中文

Why Nino

  • Fastest. Up to 7.2× faster serialization than MemoryPack, and up to 9.5× faster deserialization into existing objects. Benchmarks
  • Safe on untrusted input. Crafted bytes cannot crash the process, read past the input, allocate out of proportion or name a type to create; every invalid input throws one NinoDataException. Untrusted data
  • Zero allocation. Serialize into an IBufferWriter<byte>, deserialize into existing or pooled objects: nothing allocated per call, thread-safe, with no locks on the hot path. Zero allocation
  • Everything at compile time. No reflection, no IL emit, no registration, no init call: works on IL2CPP, Native AOT and HybridCLR hot updates, and compiles up to 221× faster than v3. Platforms
  • The same bytes everywhere. Identical bytes on every runtime and CPU, and from Go, Rust and TypeScript through the code nino-gen writes for your types. Other languages
  • Rich types that evolve. Polymorphism without tags, keyed and version-tolerant types, reference tracking, every BCL collection. Supported types
  • Mistakes caught as you type. 33 analyzer diagnostics, many with a one-click fix. Analyzers

Install

dotnet add package Nino --prerelease    # .NET and Godot: the runtime and the generator
openupm add com.jasonxudeveloper.nino   # Unity 2022.3+

Nino v4 is a prerelease, so --prerelease is required: without it NuGet installs 3.9.x, which cannot read or write v4 data. Optional packages: Nino.Immutable (System.Collections.Immutable), Nino.AspNetCore (MVC formatters, Minimal API bodies and results), Nino.Codegen (your types as TypeScript, Go or Rust after each build; Nino.Codegen.Tool is the same as the nino-gen command). Installation for .NET, Unity and Godot.

Quick start

using Nino.Core;

[NinoType]
public sealed class Order
{
    public long Id;
    public string Customer;
    public List<OrderLine> Lines;
}

byte[] bytes = NinoSerializer.Serialize(order);
Order copy = NinoDeserializer.Deserialize<Order>(bytes);
NinoDeserializer.Deserialize(bytes, ref copy); // fills the same instance in place

Polymorphism needs no tags: a value declared as its base is read back as its runtime type.

[NinoType] public abstract class Message { public int Seq; }
[NinoType] public sealed class Chat : Message { public string Text; }

byte[] bytes = NinoSerializer.Serialize<Message>(new Chat { Text = "hi" });
Message msg = NinoDeserializer.Deserialize<Message>(bytes); // a Chat again

Next: your first types, evolving data, reference tracking, pooling and the advanced guides.

AI coding assistants

Nino ships a skill for Claude Code, Codex, Cursor, Copilot and other agents:

npx skills add JasonXuDeveloper/Nino

The nino-serialization skill teaches your assistant to declare [NinoType]s, pick the format for data that outlives a release, use the fast and zero-allocation forms, and fix every NINO diagnostic. The docs are written for models too: llms.txt, llms-full.txt, and every page as Markdown (add .md to its URL).

Benchmarks

Nino v4 vs Nino v3 vs MemoryPack: serialize and deserialize speed

BenchmarkDotNet 0.15.8, .NET 10.0.14, server GC, Intel Xeon 6973P-C 3.54 GHz; Nino v4 and MemoryPack 1.21.4 in one run, Nino 3.3.13 from NuGet directly before it on the same machine. Payloads are about the same size (SimpleClass: 1,069 bytes in v4, 1,152 in v3, 1,148 in MemoryPack). Every case and the method: docs/v4-benchmarks.md; the notes of each release carry that release's numbers.

Every case, Arm64, MessagePack and protobuf-net: .NET benchmarks; Unity with Burst; Go, Rust and TypeScript. Arrays of tuples and structs and string conversion use AVX-512, AVX2, SSSE3, Arm64 and WebAssembly SIMD (Burst kernels in Unity), with portable code writing the same bytes elsewhere: SIMD.

Built for

⚙️ Services & IPC No per-call allocations, safe concurrent use; ASP.NET Core bodies as application/x-nino.
🌐 RPC & networking Straight into a PipeWriter, pooled messages, and a crafted message throws instead of taking the server down.
📨 Message queues · 🗄️ Caching · 💾 Storage Polymorphic events, small payloads, and formats that let fields be added, reordered and removed across releases.
🧩 Web, Node, Go & Rust Types and codecs generated after each build, so browsers and services read and write the same bytes as .NET.
🎮 Unity 2022.3+, Mono and IL2CPP, HybridCLR without an init call, Burst SIMD kernels, AnimationCurve and Gradient built in.
👾 Godot 4 (.NET) A regular NuGet package; Vector3, Transform3D and other math structs are copied as raw memory.

Compared with MemoryPack

MemoryPack's README now calls it "a high-performance serialization format for trusted data only" (MemoryPack README); Nino is built for data from network peers and user files (details).

Nino v4 MemoryPack 1.21.4
Untrusted input built for it: bounded allocation and stack, one exception type trusted data only, per its README
Serialize classes and polymorphic types 3.5–7.2× faster
Deserialize classes and polymorphic types 1.7–2.1× faster
Raw struct arrays at least on par without padding (a block copy in both); padding zeroed padding copied as is, in the platform's layout
Deserialize into existing objects 0 B, up to 9.5× faster (in place) overwrite mode: clears collections and allocates their elements again
Polymorphism automatic type ids, any base class or interface, generic bases included [MemoryPackUnion] tags you maintain, not on generic types
Keyed members, reference tracking, object pools ✅ version tolerance and circular references, no pools
Unity ✅ 2022.3+, one OpenUPM package, netstandard2.0 and 2.1 ✅ 2022.3.12f1+, NuGetForUnity plus a git package, netstandard2.1

While benchmarking we found three types MemoryPack 1.21.4 does not round-trip (BigInteger, BitArray on .NET 10, tuples between runtimes); Nino writes them by value. The full comparison covers them, what MemoryPack has that Nino does not, and how to switch. Also compared: MessagePack and protobuf-net.

v4 vs v3

v4 is a rewrite of the runtime and the generator. Its binary format is not compatible with v3.

v4 vs v3 (3.3.13)
Serialize 2.11× faster (class), 2.49× faster (class array), 1.37× faster (struct), on par (struct array)
Deserialize 1.55× faster (class), 1.55× faster (class array), on par (struct), on par (struct array), while adding reference tracking, reuse deserialization and payload validation
Compiling the generated code 51× faster at 330 types (42.9 s → 0.84 s), 221× faster at 1,100 types (462 s → 2.1 s)
Running the generator 3.1× faster; after an edit, only that type is re-generated (8.3× faster)
Generated code 14× smaller source, 5× smaller IL

Everything new: what's new in v4, the changelog and the migration guide; internals are in docs/v4-design.md.

Contributing

Issues and pull requests are welcome. CONTRIBUTING.md covers building, the test matrix and releasing.

MIT License · Made by JasonXuDeveloper

About

The fastest binary serializer for C#. Source-generated, zero-allocation: services, RPC, messaging, caching, storage, Unity and Godot.

Topics

Resources

Contributing

Stars

655 stars

Watchers

15 watching

Forks

Releases

Used by

Contributors

Languages