JSON to Dart
Convert JSON to Dart classes for Flutter online, with fromJson and toJson methods or json_serializable annotations, null safety and nested models.
Runs in your browser · Nothing uploaded · No sign-up
Something not working, or missing a feature? Send feedback
About the JSON to Dart
The JSON to Dart converter generates Dart classes for Flutter from a JSON sample, with fromJson factories and toJson methods that follow the null-safety rules. Nested objects become their own classes, arrays become List<T>, and keys missing from some items become nullable fields. You can also generate classes for json_serializable.
Conversion happens in your browser, so your files and records stay private.
How to use the JSON to Dart
- Paste a JSON sample and set the root class name.
- Choose hand-written fromJson / toJson, or json_serializable annotations.
- Copy the code into your project. For json_serializable, run dart run build_runner build to create models.g.dart.
Example
Input
{
"id": 7,
"fullName": "Grace Hopper",
"email": null,
"roles": ["admin"],
"team": { "name": "Compilers", "size": 4 },
"projects": [
{ "name": "COBOL", "year": 1959 },
{ "name": "A-0", "year": 1952, "archived": true }
]
}Result
class User {
final int id;
final String fullName;
final dynamic email;
final List<String> roles;
final Team team;
final List<Project> projects;
const User({
required this.id,
required this.fullName,
required this.email,
required this.roles,
required this.team,
required this.projects,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: (json['id'] as num).toInt(),
fullName: json['fullName'] as String,
email: json['email'],
roles: (json['roles'] as List<dynamic>).map((e) => e as String).toList(),
team: Team.fromJson(json['team'] as Map<String, dynamic>),
projects: (json['projects'] as List<dynamic>).map((e) => Project.fromJson(e as Map<String, dynamic>)).toList(),
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'fullName': fullName,
'email': email,
'roles': roles,
'team': team.toJson(),
'projects': projects.map((e) => e.toJson()).toList(),
};
}
}
class Project {
final String name;
final int year;
final bool? archived;
const Project({
required this.name,
required this.year,
this.archived,
});
factory Project.fromJson(Map<String, dynamic> json) {
return Project(
name: json['name'] as String,
year: (json['year'] as num).toInt(),
archived: json['archived'] == null ? null : json['archived'] as bool,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'year': year,
if (archived != null) 'archived': archived,
};
}
}
class Team {
final String name;
final int size;
const Team({
required this.name,
required this.size,
});
factory Team.fromJson(Map<String, dynamic> json) {
return Team(
name: json['name'] as String,
size: (json['size'] as num).toInt(),
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'size': size,
};
}
}archived is missing from one project, so it is nullable and left out of toJson when null. email was only ever null, so it is dynamic.
Common mistakes
- Forgetting the generated part file. With json_serializable, the part 'models.g.dart' line fails until you run dart run build_runner build. Rename it if you save the file under another name.
- Casting numbers with as double. A JSON 1 decodes to an int, so (x as double) throws. Cast through num, as the generated code does.
- Treating nullable as optional. A key that is present with a null value and a key that is missing both give a null field. If you must tell them apart, check the map with containsKey before using the model.
Works well with the JSON to Dart
- JSON Formatter: tidy and check the JSON before generating classes.
- JSON Validator: find syntax errors in the sample first.
- JSON to Kotlin: generate matching models for an Android client.
Frequently asked questions
fromJson / toJson or json_serializable?
Hand-written methods need no packages or build step, and are enough for most API responses. json_serializable generates that code from annotations, which saves effort for large models but needs json_annotation, json_serializable and build_runner.
Why is a field typed dynamic?
Its value was always null in the sample, or it held values of different kinds, so no single type fits. Use a sample in which the field has a real value.
Why do numbers use (x as num).toInt()?
A JSON number such as 1 can arrive as an int or a double, depending on the decoder. Casting through num works for both, while a plain as double fails on a whole number.
Which Dart version does the code need?
Dart 2.12 or later, because the classes use null safety (String?) and required named parameters.
Related tools
JSON to CSV
Convert JSON arrays to CSV online with automatic column detection, nested object flattening and custom delimiters. Open the result in Excel or Sheets.
CSV to JSON
Convert CSV to a JSON array online with header detection, type inference and delimiter auto-detection. Turn spreadsheet exports into data for APIs and code.
JSON to XML
Convert JSON to well-formed XML online with a configurable root element and attribute support. Validate the input and download the XML file.
XML to JSON
Convert XML to JSON online, keeping attributes and turning repeated elements into arrays. Malformed XML is reported with its location.
JSON to YAML
Convert JSON to clean, human-readable YAML online. Turn API responses and package files into config for Kubernetes, Docker Compose or CI pipelines.
YAML to JSON
Convert YAML documents to formatted JSON online with syntax validation. Errors are reported by line, so broken indentation is quick to find and fix.