Introduction
Serde is the de facto serialization framework for Rust, used by virtually every Rust project that handles structured data. Its derive macros generate zero-overhead serialization code at compile time, and its generic data model lets a single struct work with JSON, TOML, YAML, bincode, and dozens of other formats without code changes.
What Serde Does
- Generates
SerializeandDeserializeimplementations via derive macros with no runtime reflection - Supports a wide range of formats through independent crate adapters (serde_json, toml, serde_yaml, etc.)
- Handles complex types including enums with data, nested structs, maps, optional fields, and custom types
- Provides field-level attributes for renaming, skipping, flattening, and defaulting during deserialization
- Achieves zero-copy deserialization for formats that support borrowing from the input buffer
Architecture Overview
Serde separates the data model from the format implementation. The Serialize and Deserialize traits define how a type maps to Serde's abstract data model of 29 types. Format crates implement Serializer and Deserializer traits to convert between the data model and a specific wire format. The derive macro generates trait implementations at compile time, producing code that the compiler can fully inline and optimize, resulting in performance comparable to hand-written serialization.
Self-Hosting & Configuration
- Add
serdewith thederivefeature to yourCargo.toml - Add a format crate like
serde_json,toml, orserde_yamlas needed - Annotate structs and enums with
#[derive(Serialize, Deserialize)] - Use
#[serde(...)]attributes to customize field names, defaults, and skip conditions - For no-std environments, disable the default
stdfeature in Cargo.toml
Key Features
- Compile-time code generation with zero runtime overhead
- Format-agnostic: one struct definition works with any supported format
- Rich attribute system for field renaming, flattening, tagging, and custom logic
- Zero-copy deserialization for high-performance parsing of large payloads
- Ecosystem of 100+ community format crates from CBOR to Avro
Comparison with Similar Tools
- encoding/json (Go) — uses runtime reflection; Serde generates code at compile time for better performance
- Jackson (Java) — annotation-driven with runtime processing; Serde achieves similar flexibility at zero runtime cost
- Protobuf (prost) — schema-first binary format; Serde is format-agnostic and works with human-readable formats
- rkyv — Rust zero-copy archive format; Serde supports more formats and is the ecosystem standard
- bincode — binary format crate that uses Serde; it is a format backend, not a competing framework
FAQ
Q: Does Serde work in no-std environments?
A: Yes. Disable the std feature in Cargo.toml and use alloc or fully no-alloc deserializers.
Q: How do I rename fields for JSON output?
A: Use #[serde(rename = "fieldName")] on individual fields or #[serde(rename_all = "camelCase")] on the struct.
Q: Can I deserialize untagged enums?
A: Yes. Use #[serde(untagged)] and Serde will try each variant in order until one succeeds.
Q: What is the performance overhead? A: Near zero. The derive macro generates specialized code that the compiler inlines, matching hand-written serialization in benchmarks.