JSON to Dart Converter – Free, Online, Private
Generate Dart classes with a fromJson factory from a JSON sample. Nested objects and lists are cast in the factory, and missing keys are optional.
How to convert JSON to Dart
- Paste the JSON a Flutter or server app decoded with jsonDecode.
- Copy the classes. Each one has a const constructor and a fromJson factory.
- Replace Object or dynamic where the sample was a union or an empty array, then run the analyzer.
Classes and fromJson
Each JSON object becomes a class with final fields, a const constructor, and a fromJson factory that reads a Map<String, dynamic>. Field names are camelCase. The factory still indexes the original JSON key, so a key like content-type is read as json["content-type"] even though the field is contentType. Integers are int, fractional numbers are double and read with (json[key] as num).toDouble() so a whole JSON number still converts. Booleans and strings are cast directly. Nested objects call that class's fromJson. Lists map each element. An empty list is List<dynamic>. A null, or a key absent from some merged objects, makes the field nullable and drops required from the constructor.
Numbers in Dart
dart:convert decodes every JSON number as num, and a whole number is an int at runtime. Casting a JSON integer with as double throws. The generated factory uses toDouble() for fields the sample treated as fractional, and as int for fields that were whole. If one response sends 1 and another sends 1.5 for the same key, the merged type is double and the factory calls toDouble(). A required int field will throw in fromJson if the key is missing. That is deliberate: the sample said the key was always there. Widen it to int? if the API lies. Integers bigger than 2^53 are already rounded by the time the browser parsed the sample.
Worked example
The sample user becomes class Address with city and zip, and class Root with id, name, active, tags, and address. tags is List<String> built with a map cast. address is Address.fromJson of a Map copy, so a _JsonMap from the decoder is accepted. The constructors are const, which matters for Flutter widgets that want const children, but fromJson itself is not a const context. There is no toJson. Add it if you need to post the model back. There is no json_serializable annotation and no build_runner setup. The factory is plain Dart so it compiles without a code generator. Keyword field names such as required or default get a Value suffix so the constructor stays legal.
Limits
Unions become Object. Dart's sealed classes would need a discriminator the sample does not reliably have, so the page refuses to invent one. Dates stay String. An optional nested object is decoded only when the value is not null. A list of mixed types maps elements as dynamic. The classes are not Equatable and do not implement ==. Generation is local to the browser tab. You can paste a response that contains a user record without sending that record to a server. If you want Kotlin, Swift, or PHP from the same sample, the other converters on this site use the same inference rules and only change the syntax.
Frequently asked questions
Does this need json_serializable?
No. fromJson is written out. You can still move to a generator later if the model grows.
Why toDouble()?
A JSON number that is mathematically an integer arrives as int. Casting it with as double throws. toDouble() accepts both.
Where is toJson?
It is not generated. The page only builds the read path from a sample.
What if the root is a list?
You get a typedef for the list and classes for any objects inside it.