Top Related Projects
Serialization framework for Rust
MessagePack implementation for Rust / msgpack.org[Rust]
Cap'n Proto for Rust
Quick Overview
Bincode is a binary serialization format for Rust. It's designed to be compact, fast, and deterministic, making it ideal for network protocols, file formats, and in-memory representations of data structures.
Pros
- Fast serialization and deserialization
- Compact binary format, reducing data size
- Deterministic output, useful for hashing and comparing data
- Seamless integration with Serde, Rust's popular serialization framework
Cons
- Not human-readable like JSON or YAML
- Limited cross-language support compared to more universal formats
- May require additional steps for backward compatibility when evolving data structures
- Not suitable for scenarios where data needs to be manually inspected or edited
Code Examples
Serializing a struct:
use serde::{Serialize, Deserialize};
use bincode;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct MyStruct {
x: i32,
y: String,
}
let my_struct = MyStruct { x: 5, y: "hello".to_string() };
let encoded: Vec<u8> = bincode::serialize(&my_struct).unwrap();
Deserializing data:
let decoded: MyStruct = bincode::deserialize(&encoded[..]).unwrap();
assert_eq!(my_struct, decoded);
Custom configuration:
use bincode::{config, Infinite};
let config = config::standard()
.with_little_endian()
.with_varint_encoding()
.limit_data_len(1024);
let encoded = config.serialize(&my_struct).unwrap();
Getting Started
-
Add bincode to your
Cargo.toml
:[dependencies] bincode = "1.3" serde = { version = "1.0", features = ["derive"] }
-
In your Rust code:
use serde::{Serialize, Deserialize}; use bincode; #[derive(Serialize, Deserialize)] struct MyData { // Your data fields here } // Serialize let encoded: Vec<u8> = bincode::serialize(&my_data).unwrap(); // Deserialize let decoded: MyData = bincode::deserialize(&encoded[..]).unwrap();
Competitor Comparisons
Serialization framework for Rust
Pros of serde
- More versatile, supporting multiple serialization formats (JSON, YAML, TOML, etc.)
- Extensive ecosystem with numerous integrations and extensions
- Highly customizable with derive macros and attributes
Cons of serde
- Slightly more complex to use due to its flexibility
- May have a larger binary size when compiled, especially with multiple formats
Code Comparison
serde:
#[derive(Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
bincode:
#[derive(Encode, Decode)]
struct Point {
x: i32,
y: i32,
}
Key Differences
- serde is a general-purpose serialization framework, while bincode focuses on binary serialization
- bincode is more lightweight and specialized for binary format
- serde requires separate serializer/deserializer crates for each format, bincode includes everything in one crate
Use Cases
- serde: Projects requiring multiple serialization formats or complex data structures
- bincode: Performance-critical applications with simple data structures, focusing on binary serialization
Community and Ecosystem
- serde has a larger community and more third-party integrations
- bincode is more focused but still well-maintained and actively developed
Performance
- bincode generally offers better performance for binary serialization
- serde's performance varies depending on the chosen format, but can be optimized for specific use cases
MessagePack implementation for Rust / msgpack.org[Rust]
Pros of msgpack-rust
- Supports a wider range of data types, including custom types
- Offers better interoperability with other languages and systems
- Provides more flexible serialization options
Cons of msgpack-rust
- Generally slower serialization and deserialization compared to bincode
- Larger encoded size for most data structures
- More complex API, potentially requiring more code to use effectively
Code Comparison
msgpack-rust:
use rmp_serde::{Serializer, Deserializer};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct MyStruct { /* ... */ }
let mut buf = Vec::new();
my_struct.serialize(&mut Serializer::new(&mut buf)).unwrap();
let deserialized: MyStruct = Deserialize::deserialize(&mut Deserializer::new(&buf[..])).unwrap();
bincode:
use bincode::{serialize, deserialize};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct MyStruct { /* ... */ }
let encoded: Vec<u8> = serialize(&my_struct).unwrap();
let decoded: MyStruct = deserialize(&encoded[..]).unwrap();
The code comparison shows that bincode offers a simpler API with fewer lines of code required for basic serialization and deserialization operations. However, msgpack-rust provides more control over the serialization process, which can be beneficial for complex use cases or when interoperability is a priority.
Cap'n Proto for Rust
Pros of Cap'n Proto Rust
- Schema-based serialization with strong type safety
- Supports zero-copy deserialization for improved performance
- Offers advanced features like RPC and versioning
Cons of Cap'n Proto Rust
- More complex setup and usage compared to Bincode
- Larger binary size due to additional features
- Steeper learning curve for developers new to the ecosystem
Code Comparison
Cap'n Proto Rust:
#[derive(Clone, Copy, Debug)]
pub struct Person<'a> {
pub name: capnp::text::Reader<'a>,
pub age: u32,
}
Bincode:
#[derive(Serialize, Deserialize, Debug)]
struct Person {
name: String,
age: u32,
}
Cap'n Proto Rust requires defining schemas separately and generating Rust code from them, while Bincode uses simple derive macros on standard Rust structs. Cap'n Proto offers more advanced features but at the cost of increased complexity, while Bincode provides a simpler, more straightforward approach to serialization and deserialization.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Bincode
A compact encoder / decoder pair that uses a binary zero-fluff encoding scheme. The size of the encoded object will be the same or smaller than the size that the object takes up in memory in a running Rust program.
In addition to exposing two simple functions
(one that encodes to Vec<u8>
, and one that decodes from &[u8]
),
binary-encode exposes a Reader/Writer API that makes it work
perfectly with other stream-based APIs such as Rust files, network streams,
and the flate2-rs compression
library.
API Documentation
Bincode in the Wild
- google/tarpc: Bincode is used to serialize and deserialize networked RPC messages.
- servo/webrender: Bincode records WebRender API calls for record/replay-style graphics debugging.
- servo/ipc-channel: IPC-Channel uses Bincode to send structs between processes using a channel-like API.
- ajeetdsouza/zoxide: zoxide uses Bincode to store a database of directories and their access frequencies on disk.
Example
use bincode::{config, Decode, Encode};
#[derive(Encode, Decode, PartialEq, Debug)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Encode, Decode, PartialEq, Debug)]
struct World(Vec<Entity>);
fn main() {
let config = config::standard();
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
let encoded: Vec<u8> = bincode::encode_to_vec(&world, config).unwrap();
// The length of the vector is encoded as a varint u64, which in this case gets collapsed to a single byte
// See the documentation on varint for more info for that.
// The 4 floats are encoded in 4 bytes each.
assert_eq!(encoded.len(), 1 + 4 * 4);
let (decoded, len): (World, usize) = bincode::decode_from_slice(&encoded[..], config).unwrap();
assert_eq!(world, decoded);
assert_eq!(len, encoded.len()); // read all bytes
}
Specification
Bincode's format is specified in docs/spec.md.
FAQ
Is Bincode suitable for storage?
The encoding format is stable, provided the same configuration is used. This should ensure that later versions can still read data produced by a previous versions of the library if no major version change has occurred.
Bincode 1 and 2 are completely compatible if the same configuration is used.
Bincode is invariant over byte-order, making an exchange between different architectures possible. It is also rather space efficient, as it stores no metadata like struct field names in the output format and writes long streams of binary data without needing any potentially size-increasing encoding.
As a result, Bincode is suitable for storing data. Be aware that it does not implement any sort of data versioning scheme or file headers, as these features are outside the scope of this crate.
Is Bincode suitable for untrusted inputs?
Bincode attempts to protect against hostile data. There is a maximum size
configuration available (Configuration::with_limit
), but not enabled in the
default configuration. Enabling it causes pre-allocation size to be limited to
prevent against memory exhaustion attacks.
Deserializing any incoming data will not cause undefined behavior or memory issues, assuming that the deserialization code for the struct is safe itself.
Bincode can be used for untrusted inputs in the sense that it will not create a security issues in your application, provided the configuration is changed to enable a maximum size limit. Malicious inputs will fail upon deserialization.
What is Bincode's MSRV (minimum supported Rust version)?
Bincode 2.0 is still in development and does not yet have a targeted MSRV. Once 2.0 is fully released the MSRV will be locked. After this point any changes to the MSRV are considered a breaking change for semver purposes.
Why does bincode not respect #[repr(u8)]
?
Bincode will encode enum variants as a u32
. If you're worried about storage size, we can recommend enabling Configuration::with_variable_int_encoding()
. This option is enabled by default with the standard
configuration. In this case enum variants will almost always be encoded as a u8
.
Currently we have not found a compelling case to respect #[repr(...)]
. You're most likely trying to interop with a format that is similar-but-not-quite-bincode. We only support our own protocol (spec).
If you really want to use bincode to encode/decode a different protocol, consider implementing Encode
and Decode
yourself. bincode-derive
will output the generated implementation in target/generated/bincode/<name>_Encode.rs
and target/generated/bincode/<name>_Decode.rs
which should get you started.
Top Related Projects
Serialization framework for Rust
MessagePack implementation for Rust / msgpack.org[Rust]
Cap'n Proto for Rust
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot