How do I serialize a Rust struct to JSON?

Walkthrough

Serializing data structures to JSON is one of the most common tasks in Rust applications, especially for web services and APIs. The serde crate, paired with serde_json, provides a powerful and ergonomic way to handle this.

The key steps are:

  1. Add serde and serde_json to your Cargo.toml with the derive feature enabled
  2. Annotate your struct with #[derive(Serialize)]
  3. Use serde_json::to_string() or to_string_pretty() to serialize

Serde handles all the heavy lifting—converting Rust types to their JSON equivalents, managing field names, and even allowing customization through attributes like #[serde(rename = "...")].

Code Example

# Cargo.toml
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
use serde::Serialize;
 
#[derive(Serialize)]
struct User {
    id: u64,
    username: String,
    email: String,
    active: bool,
}
 
fn main() -> serde_json::Result<()> {
    let user = User {
        id: 42,
        username: String::from("rustacean"),
        email: String::from("rustacean@example.com"),
        active: true,
    };
 
    // Compact JSON output
    let json = serde_json::to_string(&user)?;
    println!("Compact: {}", json);
    // Output: {"id":42,"username":"rustacean","email":"rustacean@example.com","active":true}
 
    // Pretty-printed JSON (useful for debugging or human-readable output)
    let pretty = serde_json::to_string_pretty(&user)?;
    println!("Pretty:\n{}", pretty);
    // Output:
    // {
    //   "id": 42,
    //   "username": "rustacean",
    //   "email": "rustacean@example.com",
    //   "active": true
    // }
 
    Ok(())
}

Summary

  • Use #[derive(Serialize)] to make a struct serializable
  • serde_json::to_string() produces compact JSON
  • serde_json::to_string_pretty() produces human-readable JSON with indentation
  • Serde attributes like #[serde(rename)] allow customization of field names in the output