Convert JSON to Dart classes with fromJson and toJson, or json_serializable models
A free JSON to Dart converter: paste JSON and get Dart classes back instantly. Choose a plain class with hand-written fromJson and toJson, or a class annotated for json_serializable that build_runner completes. Fields are final and typed from the data (int, double, bool, String, List and nullable types), nested objects become their own classes, and numbers that JSON writes without a decimal point are still read into double fields correctly. Names Dart reserves or privatises are renamed so the file analyzes without warnings. Conversion runs entirely in your browser, so your JSON is never uploaded to a server.
Output formats: Plain class (Final fields with hand-written fromJson and toJson), json_serializable (Annotated class; build_runner writes the .g.dart part).
| Option | What it does |
|---|---|
| Root Class Name | Names the top-level Class. |
| Field Naming Convention | One of camelCase, snake_case, PascalCase, Preserve Original. Defaults to camelCase. |
| Type for null values | Either dynamic or String, used when a key is null in every sample. |
| Separate Classes | Write each class to its own .dart file, each importing the files it refers to. Off (the default) puts every class in one file, so Copy All pastes into a single file that analyzes. |
| Map original JSON keys | Read and write each field under the original JSON key (a @JsonKey(name:) for json_serializable). Without it a field only binds to a key spelled exactly like it, so a snake_case key is not read into a camelCase field. |
| JSON value | Dart type |
|---|---|
| string | String |
| integer | int |
| decimal | double |
| true / false | bool |
| ISO-8601 timestamp | String |
| array | List<T> |
| object | nested class |
| null or missing in some samples | T? |
| null | dynamic (configurable) |
{
"id": 1,
"product_name": "Wireless Mouse",
"tags": ["electronics"]
}
class Product {
final int id;
final String productName;
final List<String> tags;
const Product({
required this.id,
required this.productName,
required this.tags,
});
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json['id'] as int,
productName: json['product_name'] as String,
tags: (json['tags'] as List<dynamic>).map((e) => e as String).toList(),
);
Map<String, dynamic> toJson() => {
'id': id,
'product_name': productName,
'tags': tags,
};
}
Paste your JSON into the input pane and the Dart classes appear beside it immediately. Set the root class name, pick Plain class or json_serializable, then copy the code or download it. Build an object with Root.fromJson(jsonDecode(source) as Map<String, dynamic>) and write it back with jsonEncode(root.toJson()). Nested JSON objects become their own classes and lists are mapped element by element.
A plain class has fromJson and toJson written out, so it works as soon as you paste it and needs no packages. json_serializable generates that code for you from annotations: add json_annotation, json_serializable and build_runner, run dart run build_runner build, and it writes the .g.dart part file. Both produce the same JSON.
JSON does not distinguish 100 from 100.0, and jsonDecode returns an int for 100, so json['price'] as double would throw. The generated code reads the value as num and calls toDouble(), which accepts both.
A field named class, in or default gets a trailing underscore (class_). A name that starts with _ would be private to the library and cannot be a named constructor parameter, so the underscore is dropped. The JSON key is kept: with Map original JSON keys on, fromJson reads and toJson writes the original key.
DateTime.parse accepts a timestamp but writes it back in a different form (fractional digits, the zone), so the document would no longer round-trip. A timestamp stays a String; call DateTime.parse where you need a DateTime.
No. Parsing, type inference, and code generation all run in your browser using JavaScript. Your JSON is never sent to a remote server, and there is no account to create. The page keeps your last input and settings in your own browser (localStorage) so they survive a reload; nothing is stored anywhere else.
The conversion itself never transmits your JSON, so a confidential payload does not leave your machine. You can verify this: open your browser DevTools, switch to the Network tab, and convert something — no request carries your data. Two things to know: your last input is saved in your browser's localStorage (clear site data to remove it), and the Copy Link button embeds your JSON in the link, so anyone who opens that link, and the server that receives the request, can see it. Only share such links where you are comfortable with that.
No. The generator is free to use with no sign-up and no usage limits.
Each nested JSON object becomes its own named type, derived from the key it appeared under. Arrays of objects are widened across every element, so a field that is a whole number in one element and a fraction in another gets a type that holds both.