The fastest binary serializer for C#.
Source-generated, zero-allocation, thread-safe and safe on untrusted input.
For .NET, Unity (Mono and IL2CPP), Godot, Native AOT and HybridCLR, with Go, Rust and TypeScript writing and reading the identical bytes.
Website · Getting started · What's new in v4 · Benchmarks · 中文
- Fastest. On 12 real-world workloads it serializes —× faster than MemoryPack, —× than MessagePack, —× than protobuf-net, —× than Google.Protobuf and —× than System.Text.Json. Benchmarks
- SIMD everywhere, Burst in Unity. Hand-written vector paths for AVX-512, AVX2, SSSE3, Arm64 and WebAssembly move tuples, padded structs and strings; Burst kernels in Unity, vector kernels in Go, Rust and TypeScript, and a portable fallback that writes the same bytes. SIMD
- 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; thread-safe, no locks on the hot path. Zero allocation - Everything at compile time. No reflection, no IL emit, no registration: runs on IL2CPP, Native AOT and HybridCLR hot updates. Platforms
- The same bytes everywhere. Every runtime and CPU writes identical bytes, and so do Go, Rust and TypeScript,
which read and write your types through the code
nino-gengenerates. Other languages - Rich types that evolve. Polymorphism without tags, version-tolerant and keyed types, reference tracking, every BCL collection. Supported types
- Mistakes caught as you type. 33 analyzer diagnostics, many with a one-click fix. Analyzers
dotnet add package Nino --prereleaseThe runtime and the source generator, for .NET Standard 2.0 to .NET 10, Native AOT and Godot 4. v4 is a prerelease:
without --prerelease NuGet installs 3.9.x, which cannot read v4 data. Add-ons: Nino.Immutable, Nino.AspNetCore, and Nino.Codegen, which writes your types as Go, Rust or TypeScript
after each build (guide).
openupm add com.jasonxudeveloper.ninoUnity 2022.3+, Mono and IL2CPP, HybridCLR. Unity guide
go get github.com/JasonXuDeveloper/Nino/runtimes/go/v4Go 1.22+, no dependencies. Use the code Nino.Codegen writes, or map your own structs with struct tags.
Go guide
cargo add nino-serializationRust 1.88+. Use the code Nino.Codegen writes, or derive on your own structs with --features derive.
Rust guide
npm install nino-serializationNode.js and browsers. Optional: Nino.Codegen can write the runtime next to the code it generates.
TypeScript guide
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 placePolymorphism 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 againNext: your first types, evolving data, reference tracking, pooling and the advanced guides.
npx skills add JasonXuDeveloper/NinoThe nino-serialization skill
teaches Claude Code, Codex, Cursor, Copilot and other agents to declare [NinoType]s, pick the right format and fix
every NINO diagnostic. The docs are also in llms.txt and
llms-full.txt.
| 12 real-world workloads | Serialize | Deserialize |
|---|---|---|
| vs MemoryPack | —× faster | —× faster |
| vs MessagePack | —× faster | —× faster |
| vs protobuf-net | —× faster | —× faster |
| vs Google.Protobuf | —× faster | —× faster |
| vs System.Text.Json | —× faster | —× faster |
| Into existing objects | — | 0 B, up to 9.5× faster than MemoryPack |
The workloads: jvm-serializers' MediaContent and a Stack Exchange API page (the models of MessagePack's and
MemoryPack's benchmarks); an RPC call whose result is an interface, a cached profile written by the previous version,
an event store page of two-level event hierarchies in generic envelopes, and a log batch; and what games send: a
state-sync snapshot read into the client's copy, lockstep input frames, an MMO AOI update, an SLG map region and a card
battle replay that share objects, and an idle game's save from the previous version. Each library uses its fastest
API (Google.Protobuf its own generated messages, System.Text.Json source-generated UTF-8) and, where it lacks a
feature, its usual workaround (copies for shared objects, a new instance instead of reading into one). A range covers
the workloads Nino wins by more than 5%; every time is in the docs.
BenchmarkDotNet 0.15.8, .NET 10.0.14, server GC, Intel Xeon 6973P-C 3.54 GHz, on GitHub's runners; all libraries in one run, Nino 3.3.13 from NuGet directly before it on the same machine. The Stack Exchange page takes — bytes in Nino, — in MemoryPack, — in MessagePack, — in protobuf (both libraries) and — in JSON. Method and every case: docs/v4-benchmarks.md.
More: every .NET case and Arm64, Unity with Burst and Go, Rust and TypeScript.
- 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 and storage: polymorphic events, small payloads, fields added, reordered and removed across releases.
- Web, Node, Go & Rust: types and codecs generated after each build, writing and reading the same bytes as .NET.
- Unity: Mono and IL2CPP, HybridCLR without an init call, Burst SIMD kernels,
AnimationCurveandGradientbuilt in. - Godot 4 (.NET): a regular NuGet package;
Vector3,Transform3Dand other math structs copied as raw memory.
MemoryPack describes itself as "for trusted data only" (its README); Nino is built for data from network peers and user files.
| Nino v4 | MemoryPack 1.21.4 | |
|---|---|---|
| Untrusted input | built for it: bounded allocation and stack, one exception type | trusted data only |
| Deserialize into existing objects | 0 B (in place) | 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 | all three | version tolerance and circular references, no pools |
| Unity | 2022.3+, one OpenUPM package | 2022.3.12f1+, NuGetForUnity plus a git package |
The full comparison covers the three types MemoryPack does not round-trip and how to switch; also vs MessagePack and vs protobuf-net.
v4 rewrote 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) |
| Build | generated code compiles 221× faster at 1,100 types (462 s → 2.1 s); 14× smaller source |
What's new in v4 · Changelog · Migration guide
Issues and pull requests are welcome; see CONTRIBUTING.md. Report security issues privately as SECURITY.md describes.