DevToolsmith

JSON to Dart Converter for Flutter

Paste JSON to generate null-safe Dart model classes with fromJson and toJson, ready for Flutter. Nested objects and lists get their own classes, and you can switch to json_serializable annotations.

Runs 100% in your browser — nothing is uploaded

JSON
Tip: drop a file here361 chars · 361 bytes · 14 lines
Dart classes
2,432 chars · 2,432 bytes · 93 lines

Tip: paste an array of several objects — keys missing from some of them become optional (T? without required).

Example

JSON input
[
  {
    "id": 1,
    "title": "Write docs",
    "done": false,
    "priority": 2.5,
    "tags": [
      "docs"
    ],
    "owner": {
      "id": 7,
      "name": "Ada"
    }
  },
  {
    "id": 2,
    "title": "Ship it",
    "done": true,
    "priority": 1,
    "tags": [],
    "due_date": "2026-11-01"
  }
]
Generated Dart (root name: Task)
// The JSON root is an array. Decode it with:
// (jsonDecode(text) as List).map((e) => TaskItem.fromJson(e as Map<String, dynamic>)).toList()

class TaskItem {
  final int id;
  final String title;
  final bool done;
  final double priority;
  final List<String> tags;
  final Owner? owner;
  final String? dueDate;

  const TaskItem({
    required this.id,
    required this.title,
    required this.done,
    required this.priority,
    required this.tags,
    this.owner,
    this.dueDate,
  });

  factory TaskItem.fromJson(Map<String, dynamic> json) => TaskItem(
        id: json['id'] as int,
        title: json['title'] as String,
        done: json['done'] as bool,
        priority: (json['priority'] as num).toDouble(),
        tags: (json['tags'] as List<dynamic>).map((e) => e as String).toList(),
        owner: json['owner'] == null ? null : Owner.fromJson(json['owner'] as Map<String, dynamic>),
        dueDate: json['due_date'] as String?,
      );

  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'done': done,
        'priority': priority,
        'tags': tags,
        'owner': owner?.toJson(),
        'due_date': dueDate,
      };
}

class Owner {
  final int id;
  final String name;

  const Owner({required this.id, required this.name});

  factory Owner.fromJson(Map<String, dynamic> json) => Owner(
        id: json['id'] as int,
        name: json['name'] as String,
      );

  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
      };
}
  • due_date and owner only appear in one task, so they are nullable and not required.
  • priority has a decimal in one sample, so it is a double read through num.
  • Nested lists of objects are mapped with .map(...).toList() in both directions.

Using the classes

import 'dart:convert';
import 'package:http/http.dart' as http;

final res = await http.get(Uri.parse('https://api.example.com/tasks'));
final tasks = (jsonDecode(res.body) as List)
    .map((e) => TaskItem.fromJson(e as Map<String, dynamic>))
    .toList();

final body = jsonEncode(tasks.first.toJson());

With json_serializable

Pick json_serializable to get annotated classes with a part directive. Then add the packages and run the generator:

# pubspec.yaml: json_annotation under dependencies,
# json_serializable and build_runner under dev_dependencies
dart pub add json_annotation dev:json_serializable dev:build_runner

# Generate the *.g.dart files (add --delete-conflicting-outputs after renames)
dart run build_runner build

Building the same API client for iOS? Generate Swift Codable structs, or Kotlin data classes for native Android.

Frequently asked questions

How do I convert JSON to a Dart class?

Paste a JSON sample into the tool above. It writes a null-safe Dart class for every object, with final fields, a const constructor, a fromJson factory and a toJson method. Keys become camelCase field names; the original keys are kept in fromJson and toJson.

Should I use json_serializable or hand-written fromJson?

Hand-written fromJson and toJson (the default) need no packages or code generation, so you can paste the result and run it. json_serializable generates the same code from annotations with build_runner, which is easier to maintain in large apps. Switch the Dart style to get annotated classes.

Why does fromJson use (json[...] as num).toDouble()?

JSON has only one number type, so a field that is usually 2.5 can arrive as 2. jsonDecode then returns an int, and a direct as double cast throws. Reading it as num and calling toDouble() works for both.

Which fields are nullable?

Fields that are null in a sample, or missing from some objects when you paste an array, get a nullable type (String?) and are not required in the constructor. Fields present in every sample are required.