How to use Flutter/Dart’s magical ways to convert JSON data into usable structures so that you can get unstuck — and get going.
Why are you here?
You have read tons of Medium posts and watched plenty of YouTube videos and still feel a little confused. Along the way, you found various ways to convert JSON into Dart code magically. But … it doesn’t work quite right.

Let’s do this
Follow along in 5-ish steps:
1. Add three modules to your project from the command-line:
unix% flutter pub add json_serializable
unix% flutter pub add json_annotation
unix% flutter pub add build_runner
and then adjust your pubspec.yaml
file by moving two of the entries underneath dev_dependencies
to look like so:

2. Any place you intend to use this module you’ll need this header for your file (let’s say the file’s named special.dart
):
import 'package:json_annotation/json_annotation.dart';
3. Your special.dart file needs a line of code that reads:
part 'special.g.dart'
Note that weird “.g” you need to add — be sure to match this statement with your actual file name. You’ll thank me later.
4. Each time you define a class with data inside it, it will have the format:
@JsonSerializable() class Person { // required vs optional distinction gets made by whether // you say it's nullable? or not / you'll need to match it // up with what you stick in your constructor / required // means it's necessary; and if it's optional, you need // to nullable? the instance variable explicitly final String firstName, lastName; final DateTime? dateOfBirth; Person({ required this.firstName, required this.lastName, this.dateOfBirth}); // replace '<your class>' where it says Person / these // two lines of code are boilerplate that you can either // automate with a VS Code or Android Studio plugin or // resort to doing it manually ... factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json); Map<String, dynamic> toJson() => _$PersonToJson(this); }
Note that step 4’s aspect of: 1/ adding the factory, and 2/ Map calls towards the end require leap-of-faithing and adherence to changing those three (3) Person spots with diligence. Don’t think about it too much.
5. Run the code generator with:
flutter pub run build_runner build
After you run this, all the error messages should have gone away.
Using the cool enum capabilities
- Layout the enum explicitly like this:
@JsonEnum() enum Noun { @JsonValue('image') image, @JsonValue('text') text, @JsonValue('desktop') desktop, }
- Subsequently you can just refer to
Noun
and any text that readsimage
ortext
ordesktop
gets converted intoNoun.image
orNoun.text
orNoun.desktop
internally.
Debugging when things go bad
Glad you asked! I have no idea how to debug when things go wrong with this process. It can get quite contorted. In particular when you:
- Basic problem: Have any JSON keys that don’t match the
required
list - Deluxe problem: Have enums out of scope in your fancy
@JsonEnum
step
I scratch my head a little. If anyone knows out there how to do this best, do LMK. —JM
Need a JSON viewer on OS X?
This one is quite nice: https://jsonviewer.app/