Features
- Serializes in the compact and fast MessagePack format.
- Performance is on par with the highly tuned and popular MessagePack-CSharp library.
- Automatically serialize any type annotated with the PolyType
[GenerateShape]
attribute or non-annotated types by adding a 'witness' type with a similar annotation. - Fast
ref
-based serialization and deserialization minimizes copying of large structs. - NativeAOT and trimming compatible.
- Serialize only properties that have non-default values (optionally).
- Keep memory pressure low by using async serialization directly to/from I/O like a network, IPC pipe or file.
- Streaming deserialization for large or over-time sequences.
- Primitive msgpack reader and writer APIs for low-level scenarios.
- Author custom converters for advanced scenarios.
- Security mitigations for stack overflows.
- Optionally serialize your custom types as arrays of values instead of maps of names and value for more compact representation and even higher performance.
- Support for serializing instances of certain types derived from the declared type and deserializing them back to their original runtime types using unions.
- Optionally preserve reference equality across serialization/deserialization.
- Structural (i.e. deep, by-value) equality checking for arbitrary types, both with and without collision resistant hash functions.
Feature comparison
See how this library compares to other .NET MessagePack libraries.
In many cases, the ✅ or ❌ in the table below are hyperlinks to the relevant documentation or an issue you can vote up to request the feature.
Feature | Nerdbank.MessagePack | MessagePack-CSharp |
---|---|---|
Optimized for high performance | ✅ | ✅ |
Contractless data types | ✅1 | ✅ |
Attributed data types | ✅ | ✅ |
Polymorphic serialization | ✅ | ✅2 |
F# union type support | ✅ | ❌ |
Typeless serialization | ❌ | ✅ |
dynamic serialization |
✅ | ✅ |
Skip serializing default values | ✅ | ❌ |
Required and non-nullable property deserialization guaranteed | ✅ | ❌ |
Dynamically use maps or arrays for most compact format | ✅ | ❌ |
Surrogate types for automatic serialization of unserializable types | ✅ | ❌ |
Custom converters | ✅ | ✅ |
Stateful converters | ✅ | ❌ |
Deserialization callback | ✅ | ✅ |
MsgPack extensions | ✅ | ✅ |
LZ4 compression | ❌ | ✅ |
Trim-safe | ✅ | ❌ |
NativeAOT ready | ✅ | ❌3 |
Unity | ✅4 | ✅ |
Async | ✅ | ❌ |
Endless streaming deserialization | ✅ | ✅ |
Reference preservation | ✅ | ❌ |
Cyclical references | ✅ | ❌ |
JSON schema export | ✅ | ❌ |
Secure defaults | ✅ | ❌ |
Automatic hash collection deserialization in secure mode | ✅ | ✅ |
Automatic collision-resistant hash function for arbitrary types | ✅ | ❌ |
Rejection of data that defines multiple values for the same property | ✅ | ❌ |
Free of mutable statics | ✅ | ❌ |
Structural IEqualityComparer<T> for arbitrary types |
✅ | ❌ |
Security is a complex subject, and an area where Nerdbank.MessagePack is actively evolving. Learn more about how to secure your deserializer.
-
Nerdbank.MessagePack's approach is more likely to be correct by default and more flexible to fixing when it is not.↩
-
MessagePack-CSharp is limited to derived types that can be attributed on the base type, whereas Nerdbank.MessagePack allows for dynamically identifying derived types at runtime.↩
-
Although MessagePack-CSharp does not support .NET 8 flavor NativeAOT, it has long-supported Unity's il2cpp runtime, but it requires careful avoidance of dynamic features.↩
-
Particular steps are currently required, and limitations apply. See our unity doc for more information.↩