Generate Rust Structs
from JSON
Paste any JSON and instantly get Rust struct definitions with serde Serialize/Deserialize derives. Perfect for Rust API clients and data models.
Open JSON to Rust ConverterRust struct definitions in four steps
No account. No upload. No nonsense.
No Server
Your JSON never leaves your device. There is no backend to send it to.
serde Compatible
Generated structs include full serde derives and rename attributes, ready for Cargo.toml.
Works Offline
Load once and use forever — even on a plane or without internet access.
Related JSON tools
Common questions answered
Is JSON to Rust conversion free?
Yes, completely free with no account required.
What serde attributes are generated?
Each struct gets #[derive(Debug, Serialize, Deserialize)] and fields get the appropriate serde(rename) attribute when needed.
Does my data leave my browser?
No. All conversion runs in your browser — your data never leaves your device.
How are nested JSON objects handled?
Nested objects become separate named structs. Arrays become Vec<T> where T is inferred from the first element.
What Rust types does JSON map to?
JSON strings become String, integers become i64, floats become f64, booleans become bool, objects become named structs, and arrays become Vec<T>.
Converting JSON to Rust structs
Rust uses the serde library for JSON serialization. To deserialize JSON, you define a struct with #[derive(Serialize, Deserialize)] and matching fields. This tool generates complete Rust structs with serde derives, proper types (String, i64, f64, bool, Option<T>), and #[serde(rename)] attributes when JSON keys don't match Rust conventions.
The converter handles Rust-specific requirements: snake_case field names, String for owned data, Vec<T> for arrays, Option<T> for nullable fields, and nested struct definitions. When JSON keys use camelCase, it adds #[serde(rename_all = "camelCase")] at the struct level.
{
"userName": "Alice",
"age": 30,
"roles": ["admin"],
"bio": null
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Root {
user_name: String,
age: i64,
roles: Vec<String>,
bio: Option<String>,
}
Get the most out of this tool
- Add #[serde(rename_all = "camelCase")] at the struct level instead of individual rename attributes for camelCase keys.
- Use Option<T> for fields that may be null — Rust type system enforces handling the None case at compile time.
- The converter generates Serialize, Deserialize, Debug, and Clone derives — remove unused ones for cleaner code.
Ready to generate your Rust structs?
Free forever. No signup. Instant results.
Open JSON to Rust ConverterRust structs and serde for JSON
Rust is a systems programming language with a strong type system and memory safety guarantees. Working with JSON in Rust requires the serde crate (serialization/deserialization framework) combined with serde_json. This pairing is the de facto standard for JSON handling in Rust — it provides compile-time-verified serialization with zero runtime overhead compared to reflection-based approaches in other languages. The converter generates Rust structs with the appropriate serde derive macros and field annotations.
The converter maps JSON types to Rust types using serde_json conventions. JSON strings become String (owned) rather than &str (borrowed) because deserialized values must own their data. JSON integers become i64 for signed integers or u64 for unsigned. JSON floating-point numbers become f64. JSON booleans become bool. JSON null values are represented as Option<T> — a Rust enum that is either Some(value) or None, providing type-safe null handling without null pointer risks.
The #[derive(Deserialize, Serialize)] attributes added to each generated struct instruct serde to automatically generate the serialization and deserialization code at compile time through Rust's macro system. This generates zero-overhead code — the compiler produces efficient, direct serialization logic specific to each struct's fields, with no runtime reflection. The result is JSON handling that is both type-safe and as fast as hand-written code.
Rust naming conventions use snake_case for field names (my_field, not myField). JSON APIs typically also use snake_case, so many fields map directly. For JSON APIs that use camelCase (like most JavaScript-based APIs), serde provides the #[serde(rename_all = "camelCase")] attribute on the struct to automatically map between snake_case Rust fields and camelCase JSON keys. The converter adds this attribute when the JSON keys are camelCase.
Optional JSON fields require careful handling in Rust. If a JSON key might be absent in some responses, use Option<T> for the field type and add #[serde(skip_serializing_if = "Option::is_none")] to omit None values when serializing back to JSON. If a field might be null (present in JSON as null), use Option<T> — serde maps JSON null to None for Option types. Getting these annotations right prevents deserialization failures from missing fields.
Axum and Actix-web, the two most popular Rust web frameworks, both use serde_json for request and response serialization. Axum's Json extractor and Axum's Json response type both work with any Deserialize/Serialize type. Generated structs from this tool plug directly into these frameworks as request body types and response types without additional configuration. This makes the converter especially useful for Rust API development.
When developers use this tool
Additional frequently asked questions
What Cargo dependencies do I need to use the generated structs?
Add serde = { version = "1", features = ["derive"] } and serde_json = "1" to your Cargo.toml dependencies. The derive feature enables the #[derive(Serialize, Deserialize)] macros. These are the only dependencies needed for basic JSON handling with the generated structs.
How do I handle JSON fields with names that are Rust keywords?
Use serde's rename attribute: #[serde(rename = "type")] pub type_field: String. This lets you name the Rust field anything valid while mapping to the original JSON key. Alternatively, use a raw identifier: pub r#type: String, though the rename approach is more readable in most codebases.
Can I use the generated structs with tokio for async JSON handling?
Yes. serde_json works synchronously — it processes data in memory. For async HTTP requests using reqwest (which is built on tokio), use the async response.json::<T>() method which handles async I/O while using synchronous serde_json deserialization on the received bytes. No special async support is needed in the struct definitions.
How does serde handle unknown JSON fields by default?
By default, serde_json ignores unknown fields when deserializing. To explicitly opt into this behavior, you can add #[serde(deny_unknown_fields)] to the struct, which causes deserialization to fail if the JSON contains any key not in the struct definition. This is useful for strict API validation but too rigid for forward-compatible clients.