input.json
order.dart
import 'package:json_annotation/json_annotation.dart'; part 'order.g.dart'; @JsonSerializable(explicitToJson: true) class Order { @JsonKey(name: "order_id") final String orderId; final Customer customer; final double total; @JsonKey(name: "created_at") final DateTime createdAt; final List<Item> items; const Order({ required this.orderId, required this.customer, required this.total, required this.createdAt, required this.items, }); factory Order.fromJson(Map<String, dynamic> json) => _$OrderFromJson(json); Map<String, dynamic> toJson() => _$OrderToJson(this); } @JsonSerializable(explicitToJson: true) class Customer { @JsonKey(name: "first_name") final String firstName; final String email; @JsonKey(name: "is_verified") final bool isVerified; const Customer({ required this.firstName, required this.email, required this.isVerified, }); factory Customer.fromJson(Map<String, dynamic> json) => _$CustomerFromJson(json); Map<String, dynamic> toJson() => _$CustomerToJson(this); } @JsonSerializable(explicitToJson: true) class Item { final String sku; final int quantity; final double price; final String? note; const Item({ required this.sku, required this.quantity, required this.price, this.note, }); factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json); Map<String, dynamic> toJson() => _$ItemToJson(this); }
Convert JSON to json_serializable
Paste a JSON object to generate annotated Dart classes. Save the result using the filename shown above the output, then run build_runner to generate the matching .g.dart part.
Output behavior
Each inferred object gets @JsonSerializable(explicitToJson: true), a const constructor, and fromJson and toJson methods linked to generated functions. @JsonKey(name: ...) preserves source keys such as snake_case while Dart fields use camelCase. Nested models serialize through their own toJson methods.
Project setup
flutter pub add json_annotation
flutter pub add --dev json_serializable build_runner
dart run build_runner build
Before using it
The copied file depends on its generated .g.dart part. Run build_runner again whenever you edit annotated fields or rename the source file; the part directive must match that filename.