PureDevTools

JSON to Dart Class Generator

Paste JSON, get Dart model classes — null safety, fromJson/toJson, json_serializable, freezed — copy or download as .dart

All processing happens in your browser. No data is sent to any server.

Options

426 characters

4 classes generated · 2,651 characters

Classes generated: 4Output size: 2,651 charsMode: null-safe · fromJson/toJson

You’re building a Flutter app that fetches data from a REST API. The response is a nested JSON object with dozens of fields — user profiles, nested addresses, lists of posts. Writing Dart model classes by hand means typing every field name twice (once as a property, once in the fromJson factory) and again in toJson. One typo in a string key gives you a runtime null at 2 AM instead of a compile-time error.

This tool generates the full Dart class hierarchy from any JSON in seconds, directly in your browser — your data never leaves your device.

Why Dart for Flutter Data Modeling

Dart is a strongly-typed language, and Flutter’s ecosystem leans heavily on generated code for JSON serialization. The standard Flutter approach has three tiers:

  1. Plain classes — hand-written fromJson/toJson methods. No dependencies, maximum control.
  2. json_serializable@JsonSerializable() annotation triggers build_runner to generate .g.dart files. Handles most cases with minimal boilerplate.
  3. freezed — builds on json_serializable and adds immutability, copyWith, pattern matching, and union types. The go-to for production Flutter apps.

This generator supports all three modes. Select the right one for your project, copy the output, drop it in your codebase.

How to Use This Tool

  1. Paste your JSON in the JSON Input panel (or click Load sample to try an example)
  2. Set the Root class name to match your data model (e.g. User, Product, ApiResponse)
  3. Toggle options: null safety, fromJson/toJson, json_serializable, freezed
  4. Click Copy or Download .dart to save the output
  5. If using json_serializable or freezed, run dart run build_runner build to generate the .g.dart and .freezed.dart files

The fromJson / toJson Pattern

The standard plain-Dart pattern uses a factory constructor for deserialization and an instance method for serialization:

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

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

  Map<String, dynamic> toJson() => {
    'name': name,
    'age': age,
  };
}

This pattern integrates directly with jsonDecode() from dart:convert:

import 'dart:convert';

final json = jsonDecode(responseBody);
final user = User.fromJson(json as Map<String, dynamic>);

Null Safety in Dart

Dart’s null safety (introduced in Dart 2.12, now default in all modern Flutter projects) means every type is non-nullable by default. A field typed String cannot hold null. To allow null, you must explicitly use String?.

This generator respects null safety:

If you disable null safety (legacy mode), all fields drop the ? suffix and required keywords.

json_serializable vs freezed

json_serializable

Adds @JsonSerializable() to each class and delegates actual serialization logic to generated code. The output references _$ClassNameFromJson and _$ClassNameToJson stubs that build_runner will fill in.

Add to pubspec.yaml:

dependencies:
  json_annotation: ^4.8.0

dev_dependencies:
  build_runner: ^2.4.0
  json_serializable: ^6.7.0

Then run:

dart run build_runner build --delete-conflicting-outputs

freezed

freezed generates immutable value classes with copyWith, ==, hashCode, and optional union types. It layers on top of json_serializable.

Add to pubspec.yaml:

dependencies:
  freezed_annotation: ^2.4.0
  json_annotation: ^4.8.0

dev_dependencies:
  build_runner: ^2.4.0
  freezed: ^2.4.0
  json_serializable: ^6.7.0

The generated @freezed classes look like:

@freezed
class User with _$User {
  const factory User({
    required String name,
    required int age,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

Handling Nested Objects and Arrays

The generator creates a separate named class for each nested JSON object. Given:

{
  "user": {
    "name": "Alice",
    "address": { "city": "Berlin", "zip": "10115" }
  }
}

The output will have three classes: Root, RootUser, and RootUserAddress. Nested class names are derived from the parent path using PascalCase — rename them in your IDE after generation.

For arrays of objects, all elements are merged into a single class. Fields missing in some elements become nullable (e.g. String? publishedAt).

Integration with Flutter HTTP Calls

A typical Flutter data-fetch pattern using the generated class:

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

Future<User> fetchUser(int id) async {
  final response = await http.get(Uri.parse('https://api.example.com/users/$id'));
  if (response.statusCode == 200) {
    return User.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
  }
  throw Exception('Failed to load user');
}

FAQ

Does this tool send my JSON to a server?

No. All processing happens entirely in your browser using JavaScript. Your JSON data never leaves your device.

What Dart version does the output target?

The output targets Dart 3.x with null safety enabled by default. Disable the null safety option for Dart 2.12–2.19 compatibility.

My JSON has snake_case keys but I want camelCase fields — is that handled?

Yes. The generator converts snake_case and kebab-case keys to camelCase Dart field names automatically. The original JSON key is preserved in the fromJson/toJson string literals, so deserialization still works correctly.

Can I rename the generated class names?

Yes. The class names are derived from the JSON property path. Use your IDE’s rename refactor to update all references at once after pasting the output.

What about json_serializable with custom field names?

When using json_serializable, add @JsonKey(name: 'original_key') to any field where the Dart name differs from the JSON key. The plain fromJson mode handles this inline in the fromJson factory.

What if the JSON root is an array?

The tool generates a typedef Root = List<RootItem> alias and a separate RootItem class for the array element type.

Related Tools

More JSON Tools