JSON to Rust Struct

Generate Rust serde-derive structs from a JSON sample.

Open tool

Overview

Paste a JSON sample and the generator emits Rust structs with #[derive(Serialize, Deserialize, Debug)] annotations and serde rename rules for snake_case mapping. Nested objects become their own structs; arrays of objects become Vec<T>.

It's for Rust developers consuming JSON APIs via serde_json, building CLI tools that parse third-party responses, or modelling webhook payloads. Reach for it when scaffolding types from a real response, replacing serde_json::Value placeholders, or migrating a Python/Node service to Rust.

How it works

The generator walks the JSON tree and produces a struct per object with typed fields - i64 for integers, f64 for floats, bool for booleans, String for strings, Vec<T> for arrays, Option<T> for fields that were null or missing. Field names use Rust snake_case, with #[serde(rename = "originalName")] annotations preserving the JSON key.

Default derives are Serialize, Deserialize, Debug, Clone. The output targets serde 1.x with default features and assumes you have serde = { version = "1", features = ["derive"] } and serde_json = "1" in your Cargo.toml.

Examples

  • Input:
    {"id": 1, "name": "Alex", "isActive": true}
    
    Output:
    use serde::{Deserialize, Serialize};
    
    #[derive(Debug, Clone, Serialize, Deserialize)]
    pub struct User {
        pub id: i64,
        pub name: String,
        #[serde(rename = "isActive")]
        pub is_active: bool,
    }
    
  • Nested object:
    pub struct Address { pub city: String, pub zip: String }
    pub struct User { pub address: Address, ... }
    
  • Optional field:
    #[serde(skip_serializing_if = "Option::is_none")]
    pub note: Option<String>,
    
  • Array of objects -> pub items: Vec<Item>.

FAQ

Why i64 and not i32?

JSON numbers can be larger than 32 bits and serde defaults to wider integer types to avoid overflow. Narrow to i32/u32 manually when you know the range.

What about big numbers?

JSON's number type is double-precision float. For numbers beyond 2^53, transport them as strings and use serde_with or a custom deserialiser.

How are dates handled?

ISO 8601 strings stay as String. Add chrono or time types with custom serde adapters when you want typed datetimes.

Does it produce builder patterns?

No - structs are plain field declarations. Consider derive_builder or typed-builder if you need a fluent builder API.

Try JSON to Rust Struct

An unhandled error has occurred. Reload ×