JasonXuDeveloper/Nino has 660 GitHub stars and 59 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 14:02 UTC. Last push 2026-11-15.
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
The fastest binary serializer for C#. Source-generated, zero-allocation, thread-safe and safe on untrusted input: .NET, Native AOT, Unity, Godot and HybridCLR, with Go, Rust and TypeScript writing and reading the same bytes.
Developer ToolsREADME.md
Original
Nino
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 · 中文
Why Nino
- Fastest. On 12 real-world workloads it serializes 1.5–5.4× faster than MemoryPack, 3.4–18× than MessagePack, 6.4–73× than protobuf-net, 3.9–34× than Google.Protobuf and 4.3–136× 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 on hot paths. Serialize into a reused
IBufferWriter<byte>, deserialize into existing or pooled objects; thread-safe, no locks on the hot path. Zero allocation - Everything at compile time. Generated formatters read and write your members directly: no reflection over them, 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, serialization callbacks, every BCL collection. Supported types
- Mistakes caught as you type. 44 analyzer diagnostics, many with a one-click fix, and a layout baseline that flags any change to a saved or sent type that old data or old builds could not read. Analyzers
Install
| Command | ||
|---|---|---|
| .NET, Godot 4 | dotnet add package Nino --prerelease |
.NET 8 and later (builds tuned for .NET 8 and .NET 10), .NET Standard 2.1, Native AOT; add-ons Nino.Immutable, Nino.AspNetCore, Nino.Codegen |
| Unity 2022.3+ | openupm add com.jasonxudeveloper.nino |
Mono, IL2CPP, HybridCLR · guide |
| Go 1.22+ | go get github.com/JasonXuDeveloper/Nino/runtimes/go/v4 |
generated code or struct tags · guide |
| Rust 1.88+ | cargo add nino-serialization |
generated code or --features derive · guide |
| TypeScript | npm install nino-serialization |
Node.js and browsers · guide |
v4 is a prerelease: without --prerelease NuGet installs 3.9.x, which cannot read v4 data. Nino.Codegen writes your
types as Go, Rust or TypeScript after each build (guide).
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
npx skills add JasonXuDeveloper/Nino
The 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.
Benchmarks
| 12 real-world workloads | Serialize | Deserialize |
|---|---|---|
| vs MemoryPack | 1.5–5.4× faster | 1.3–3.5× faster |
| vs MessagePack | 3.4–18× faster | 2.2–12× faster |
| vs protobuf-net | 6.4–73× faster | 3.8–35× faster |
| vs Google.Protobuf | 3.9–34× faster | 2.3–32× faster |
| vs System.Text.Json | 4.3–136× faster | 3.7–91× faster |
| Into existing objects | — | 0 B, up to 7.6× 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.
Real workloads
Basic types and structs
Polymorphism
Nullable values
Collections and common types
Reuse and pooling
Reference tracking and version tolerance
Others
BenchmarkDotNet 0.15.8, .NET 10.0.15, server GC, AMD EPYC 9V74 3.69 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 123,333 bytes in Nino, 134,223 in MemoryPack, 115,778 in MessagePack, 118,660 in protobuf (both libraries) and 208,038 in JSON. Method and every case: docs/v4-benchmarks.md.
More: every .NET case and Arm64, Unity with Burst and Go, Rust and TypeScript.
Built for
- Services & IPC: no per-call allocations, safe concurrent use; ASP.NET Core bodies as
application/x-nino. - RPC & networking: straight into a
PipeWriterand out of aPipeReader'sReadOnlySequence<byte>, 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.
Compared with other serializers
| Nino v4 | MemoryPack | MessagePack | protobuf | System.Text.Json | |
|---|---|---|---|---|---|
| Format | binary, no per-value tags | binary, memory layout | MessagePack, self-describing | Protocol Buffers, field numbers | JSON text |
| Untrusted input | safe by default, one exception type | "trusted data only" | opt-in UntrustedData |
depth limit | depth limit |
| Polymorphism | automatic, any base or interface | [MemoryPackUnion] tags |
[Union] keys |
[ProtoInclude] numbers, oneof |
[JsonDerivedType] per subtype |
| Shared and circular references | trackReferences |
circular references | no | no | ReferenceHandler.Preserve |
| Read into existing objects | in place, 0 B | clears collections, new elements | no | merges, no overwrite | members only (Populate) |
| Other languages | Go, Rust, TypeScript, generated from your C# | TypeScript | any MessagePack library | every protobuf library | every language |
protobuf covers protobuf-net and Google.Protobuf. Which to choose, and Nino's limitations: Choosing a Serializer. In depth: vs MemoryPack, vs MessagePack, vs protobuf-net.
v4 vs v3
v4 rewrote the runtime and the generator; its binary format is not compatible with v3.
| v4 vs v3 (3.3.13) | |
|---|---|
| Serialize | 1.9× faster (class), 2.4× faster (class array), on par (struct), 1.2× faster (struct array) |
| Deserialize | 1.5× faster (class), 1.5× faster (class array), on par (struct), on par (struct array) |
| Build | generated code compiles 188× faster at 1,100 types (193 s → 1.03 s); 12× smaller source |
What's new in v4 · Changelog · Migration guide
Contributing
Issues and pull requests are welcome; see CONTRIBUTING.md. Report security issues privately as SECURITY.md describes.