JSON1 / JSON to Dart
JSON to Dart
Generate Dart classes with fromJson and toJson from a JSON sample. Every nested object gets its own class, so decoding a payload never leaves you holding a raw map.
Converted output appears here as you type.
Good to know
- Every record in an array is inspected, not just the first, so a field that appears in only some of them is typed as optional rather than required.
- Identical nested shapes are emitted once and reused, and reserved words are renamed to something legal in this language.
About this tool
Dart has no runtime reflection in the mode Flutter compiles to, so there is no library that can populate a model from a map without either code generation or hand-written methods. That makes this the most verbose output of the nine targets by a wide margin: every class needs a fromJson factory and a toJson method as well as its fields.
All of it is generated. Every nested object gets its own class with its own pair of methods, so decoding leaves you holding typed models rather than a Map<String, dynamic> you keep casting at the point of use.
intJSON integers. On the web, Dart ints are JavaScript doubles, so values above 2^53 lose precision there but not on mobile.doubleFractional numbers — and the one real trap, because a JSON 1 decodes as int and will not cast to double.int?Optional or nullable, with the constructor parameter left off required so it defaults to null.finalEvery field, with a const constructor. Flutter rebuilds constantly; immutable models are what make that cheap.dynamicA field with no observable type — the one place the casts are not checked.
- Why does my double field throw at runtime?
- Because a JSON number written
1rather than1.0decodes toint, andjson['x'] as doubleon an int throws. It is the single most common failure with hand-written Dart models, and it only shows up when a value happens to arrive whole. If a field can be either,(json['x'] as num).toDouble()is the fix. - Are the fields immutable?
- Yes —
finalfields, a const constructor, and named parameters marked required where the field is not nullable. That is the conventional shape for a Flutter model, and it lets the widget tree treat instances as values, so an equality check does not force a rebuild. - Why hand-written fromJson instead of json_serializable?
- Generated code needs
build_runnerin the project and apartfile beside the class, neither of which exists when you are pasting a model into a scratch file to see if it works. These methods are complete as written — no build step, no annotations, nothing to regenerate when you change a field. - Is there equality or copyWith?
- No. Both are worth adding for a model you keep — Dart has no data classes, so
==compares identity until you write it, which means two identical responses are unequal and asetStatefires when nothing changed. It is left out because it is more generated code than the model itself, and packages like freezed do it better. - How are optional fields decided?
- Every record in an array is inspected, not just the first. A field that appears in some records and not others is typed as optional, and a value that is sometimes null widens accordingly. Generators that read only the first element get this wrong on exactly the payloads where it matters.
- What happens to a key that is a reserved word?
- It is renamed to something legal in the target language, and where the language supports it, an annotation records the original JSON key so serialisation still round-trips.
Related tools
- JSON to SwiftGenerate Swift structs conforming to Codable from a JSON sample. CodingKeys are emitted only when a key differs from its property name, so simple models stay readable.
- JSON to TypeScriptGenerate TypeScript interfaces from a JSON sample. Fields missing from some records are marked optional, and values that are sometimes null widen to a null union.
- JSON to YAMLConvert JSON to YAML. Strings that would otherwise read as booleans, numbers, or nulls are quoted so the result parses back to the same value.