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
Nounand any text that readsimageortextordesktopgets converted intoNoun.imageorNoun.textorNoun.desktopinternally.
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
requiredlist - Deluxe problem: Have enums out of scope in your fancy
@JsonEnumstep
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/