How the types are inferred
Every nested object becomes its own class, named after its key, and identical shapes share one class. Property names become PascalCase (user_name is UserName) and the original name is kept in a [JsonPropertyName] or [JsonProperty] attribute, so deserialization still matches. C# keywords such as class are escaped with @.
Number types come from the number as written: 42 is int, a whole number outside the int range is long, and 9.5 or 1.0 is double (or decimal if you tick that box). Strings shaped like ISO 8601 date-times can become DateTime or DateTimeOffset.
Arrays of objects are merged across all elements. A property missing from some elements becomes nullable, and so does one that is null in some. An array that mixes types becomes List<object>, a value that is only ever null becomes object, and the notes under the result list each of these so you can fix them by hand.
Worked example
Input:
{"id": 42, "user_name": "Ann", "class": "gold", "balance": 3000000000,
"email": null, "address": {"city": "Paris"},
"orders": [{"sku": "A1", "qty": 2}, {"sku": "B2", "qty": 1, "gift": true}]}
Output with System.Text.Json and nullable reference types:
#nullable enable
using System.Collections.Generic;
using System.Text.Json.Serialization;
public class Root
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("user_name")]
public string UserName { get; set; } = string.Empty;
[JsonPropertyName("class")]
public string Class { get; set; } = string.Empty;
[JsonPropertyName("balance")]
public long Balance { get; set; }
[JsonPropertyName("email")]
public object? Email { get; set; }
[JsonPropertyName("address")]
public Address Address { get; set; } = default!;
[JsonPropertyName("orders")]
public List<Order> Orders { get; set; } = new();
}
public class Address
{
[JsonPropertyName("city")]
public string City { get; set; } = string.Empty;
}
public class Order
{
[JsonPropertyName("sku")]
public string Sku { get; set; } = string.Empty;
[JsonPropertyName("qty")]
public int Qty { get; set; }
[JsonPropertyName("gift")]
public bool? Gift { get; set; }
}
The balance is a long, gift is nullable because only one order has it, and email is object? because a sample cannot show its real type.
Using the output in Unity
Choose Unity JsonUtility to get [Serializable] classes with public fields (public string @class;) instead of properties. Unity's documentation says JsonUtility only serializes fields of supported types, that the object you pass must be a custom type rather than a primitive or a collection such as List<T> or an array, and that JSON you deserialize must have an object at the top level, not an array. If your JSON starts with [, wrap it in a class that holds the list as a field.
Unity's serialization rules add that it does not serialize properties. The pages we checked do not describe dictionaries, so test objects with dynamic keys in your project before relying on them. In Unity mode this tool leaves date strings as string and does not use nullable annotations or records. Sources, checked on 2026-11-08: docs.unity3d.com/ScriptReference/JsonUtility.html and docs.unity3d.com/Manual/script-serialization-rules.html.
Frequently asked questions
Should I choose System.Text.Json or Newtonsoft.Json?
Pick the library your project already uses. The only difference in the output is the attribute: [JsonPropertyName] for System.Text.Json and [JsonProperty] for Newtonsoft.Json. "No attributes" is for code that maps names itself.
Why is a number a double when I expected an int?
The type follows the number as written. 1.0 or 2.5 has a decimal point, so it is a double. If it should be whole, remove the ".0" in the sample or edit the type.
Can one sample show which properties are optional?
Only partly. Properties missing from some array elements are marked nullable, but a single object cannot reveal which fields may be absent. Paste several elements, or edit the result.
What happens to an array at the root?
The class describes one item, and the notes tell you to deserialize into a list or array of it. In Unity mode the notes explain that JsonUtility needs an object at the top.
Why did two keys get different names with a number at the end?
Two keys can fold to the same C# name, for example user_id and userId. The second gets a 2 and keeps its own attribute so it still maps to the right key.
Is my JSON uploaded anywhere?
No. The conversion is plain JavaScript running on your device. Your JSON is never sent to a server.