Freezed and json_serializable in Flutter: solved exercise
Freezed and json_serializable in Flutter: solved exercise
Freezed automatically generates copyWith, ==, hashCode, toString, and fromJson/toJson for your models. It eliminates the boilerplate you would otherwise write by hand — the most common source of bugs when working with immutable data.
Problem statement
Create an immutable Post model with id, title, body, and isFavorite (with a default value). Demonstrate:
- Instance creation.
copyWithto change a single field.- Serialization to/from JSON.
- A union type
ApiResultto model success and failure.
Dependencies
Running build_runner
Solution: Post model
Solution: ApiResult union type
Full usage in an app
Files generated by build_runner
After running build_runner build, two files appear that you must not edit manually:
Add these patterns to .gitignore if you prefer not to version the generated files (requires regeneration in CI):
Or commit them to avoid regenerating on every CI build.
Common mistakes
- Forgetting
part 'post.freezed.dart': the compiler cannot find the generated types and fails with_$Post not found. - Not running build_runner after a change:
.freezed.dartfiles become stale and type errors appear. - Editing a
.freezed.dartfile by hand: it gets overwritten on the next build; all changes go in the annotated source file.
When Freezed is worth it
- Models that travel across multiple layers (API → domain → UI).
- Models that are frequently copied with small modifications.
- BLoC/Cubit states with multiple variants (union types).
- Any project lasting more than a couple of weeks.
Practical use
Freezed is the de facto standard for domain models in Flutter. You will find it in almost every production project with clean architecture, alongside Riverpod or BLoC.
Recommended next exercise
- json_serializable without Freezed: solved exercise
- DTO to domain mapper in Flutter: solved exercise
- Layered architecture in Flutter: solved exercise
- All Flutter exercises
Guided practice and next step
- More Flutter exercises
- C exercises to strengthen fundamentals
- Programming in C in 100 Solved Exercises
- View the book on Amazon (included in Kindle Unlimited)
- Subscribe to the newsletter
FAQ
Do I need to regenerate on every flutter run?
No. Generated files persist. You only regenerate when you change the annotated class.
Is Freezed compatible with Riverpod?
Yes, and they complement each other very well. StateNotifier or AsyncNotifier states in Riverpod are typically modeled with Freezed.
Can I use Freezed without json_serializable?
Yes. If you do not need fromJson/toJson, omit json_annotation and the part '*.g.dart'. You still get copyWith, ==, and toString.