How types are chosen
| JSON value | Dart type |
|---|---|
"text" | String |
42 | int |
4.5, 1.0, 1e3 | double, read with (json['x'] as num).toDouble() |
true / false | bool |
| An object with keys | A new class, named after its key |
{} | Map<String, dynamic> |
| An array | List<T>, with T taken from all of its items |
null only, or mixed types | dynamic |
Rules worth knowing
- Every item of an array is used. For a list of objects, the keys of all items are merged into one class. A key that is missing from some items, or is
nullin any of them, becomes nullable (String?). 1and1.5in the same field givedouble. The number is read from the text you paste, so1.0is adouble, as it is for Dart'sjsonDecode.- Keys become lowerCamelCase fields.
first_namebecomesfirstName, and the original key is kept infromJson,toJsonand@JsonKey. Dart keywords and names such asclass,intorhashCodeget aValuesuffix. - List item classes are named in the singular.
ordersgivesOrderandcategoriesgivesCategory. This is a simple English rule, so rename a class if the result reads oddly. Two classes with the same name get a number, such asPage2. - A root array uses its items. Pasting
[{"id": 1}]generates the item class; decode it with.map(...)on the list.
Using the generated code
With the plain Dart style, no packages are needed:
import 'dart:convert';
final user = User.fromJson(jsonDecode(body) as Map<String, dynamic>);
print(user.fullName);
final back = jsonEncode(user.toJson());With json_serializable, save the code in a file named after the part line (for example user.dart), add the packages and run the generator:
dart pub add json_annotation dev:json_serializable dev:build_runner
dart run build_runner buildIn a Flutter project, use flutter pub add instead of dart pub add. The classes use explicitToJson: true, so nested objects are converted to maps by toJson.
Limitations
- Types come from one sample. If the API sometimes sends
nullor leaves out a key that your sample has, the cast fails at runtime. Paste several items in an array, or tick Make all fields nullable. - Dates stay
String; the tool does not guessDateTimeor enums. Change them by hand if you want them parsed. - Two keys with the same structure in different places produce two classes. Merge them by hand if they are the same model.
freezedoutput is not offered yet.
The generated code was checked with dart analyze (recommended lints) and a decode-and-encode round trip on Dart 3.13.5 for a set of test payloads, in both styles.
Pasting a Flutter log
A map printed by print or debugPrint, such as {id: 1, name: Ada}, is not JSON. Use Try to repair to convert it first. Values in such logs have no quotes, so check the guessed types. The common JSON errors guide explains other parse errors, and the JSON Formatter shows their exact position.