JSON to Rust Struct Converter
Paste any JSON and get idiomatic Rust structs with serde Serialize/Deserialize derives — automatic type inference, nested structs, Option for nulls, Vec arrays, HashMap maps, and #[serde(rename)] attributes. Free, unlimited, no signup.
How to convert JSON to Rust structs
- Paste your JSON into the input panel — an API response, a config file, or any sample payload. Conversion to Rust structs happens live as you type.
- Tune the options: rename the root struct, pick derive traits (
Debug,Clone,PartialEq), choose the serde rename strategy, and toggleHashMapoutput for uniform objects. - Copy or download the generated
.rscode and drop it into your project next to theCargo.tomlsnippet below.
Cargo.toml setup
Add these dependencies once — every struct this serde struct generator emits compiles against them:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Deserialize in one line
// with the generated `Root` struct in scope:
let data: Root = serde_json::from_str(json_str)?;
JSON to Rust type mapping
This json to rust serde converter infers the most precise Rust type for every value it sees:
| JSON value | Generated Rust type | Notes |
|---|---|---|
"text" | String | Owned strings, serde-friendly |
42 | i64 | Integers map to 64-bit signed |
4.2 | f64 | Floats map to 64-bit |
true / false | bool | — |
null | Option<T> | Option<serde_json::Value> when the type is unknown |
[...] homogeneous | Vec<T> | e.g. Vec<String>, Vec<i64> |
[...] with nulls | Vec<Option<T>> | Null-safe element type |
[] or mixed types | Vec<serde_json::Value> | Always compiles, round-trips anything |
{...} nested object | named struct | Recursive, e.g. pub struct Address |
{...} uniform values* | HashMap<String, T> | *Only with the HashMap option enabled |
top-level [...] | pub type Root = Vec<Item>; | Type alias plus the item struct |
Arrays of objects are merged: the generator unions every key seen across all elements, and keys missing from some elements become Option<T> so real-world API responses with ragged shapes still deserialize.
Serde attributes this generator emits
#[serde(rename = "...")]
JSON keys are converted to idiomatic snake_case field names while the original key is preserved with #[serde(rename)] — so "userName" becomes pub user_name: String and still deserializes correctly. Keys that are not valid Rust identifiers (hyphens, spaces, leading digits) or Rust keywords like type are sanitized automatically (keywords use raw identifiers, e.g. r#type).
#[serde(rename_all = "camelCase")]
Prefer one struct-level attribute over per-field renames? The rename strategy selector adds rename_all and only falls back to explicit #[serde(rename)] for keys the convention cannot reproduce.
#[serde(skip_serializing_if = "Option::is_none")]
Every Option field gets this attribute (toggleable), so serializing a struct with None fields produces clean JSON without null noise.
Frequently asked questions
What crates do I need to compile the generated Rust structs?
Add serde with the derive feature and serde_json to your Cargo.toml: serde = { version = "1.0", features = ["derive"] } and serde_json = "1.0". Then deserialize with let data: Root = serde_json::from_str(json)?;. The generated code needs only these two crates plus the standard library.
How are JSON null values handled?
Fields whose sample value is null become Option<T> — Option<serde_json::Value> when the type cannot be inferred — so missing or null data deserializes safely instead of failing. The generator also adds #[serde(skip_serializing_if = "Option::is_none")] so None fields are omitted when you serialize back to JSON.
How do nested JSON objects become Rust structs?
Nested objects are converted recursively into their own named structs — for example the "address" object becomes pub struct Address — with fields referencing the child type. Arrays of objects are merged into a single struct, and keys missing from some elements become Option<T>.
How does the tool handle camelCase or unusual JSON keys?
Field names are converted to idiomatic snake_case and a #[serde(rename = "originalKey")] attribute preserves the exact JSON key, so deserialization keeps working. You can also switch the rename strategy to #[serde(rename_all = "camelCase")] or keep keys exactly as-is.
What happens with empty or mixed-type arrays?
Empty arrays and arrays with mixed element types become Vec<serde_json::Value>, which always compiles and round-trips any JSON. Homogeneous arrays get precise types like Vec<String> or Vec<i64>, and arrays containing nulls become Vec<Option<T>>.
When is HashMap<String, T> used instead of a struct?
Enable the "uniform objects as HashMap" option and any object whose values are all the same primitive type — for example {"labels": {"env": "prod"}} — becomes HashMap<String, String> instead of a struct with one field per key. This is ideal for dynamic key-value maps like HTTP headers or labels.
Is my JSON sent to a server?
No. The conversion runs 100% in your browser with client-side JavaScript — your JSON never leaves the page, there is no upload, no account, and no tracking. You can disconnect from the internet after the page loads and the tool keeps working.
How do I deserialize JSON into the generated struct?
Use serde_json::from_str with your root type: let data: Root = serde_json::from_str(json_str)?;. In frameworks like Axum or Actix Web you can usually deserialize request bodies directly into the struct with Json<Root>. The generated Serialize derive also lets you convert the struct back with serde_json::to_string.
Also known as: json to rust struct converter, convert json to rust struct online, rust struct generator from json, generate rust structs from json, serde json struct generator, json to serde struct, rust model generator from json, json to rust code generator, rust serde struct generator, json to rust online free.
Related JSON converters
Free tool by NRTechStudio