SkillAgentSearch skills...

Freezed

Code generation for immutable classes that has a simple syntax/API without compromising on the features.

Install / Use

/learn @rrousselGit/Freezed
About this skill

Quality Score

0/100

Supported Platforms

Zed

README

English | 한국어 | 简体中文 | 日本語 | Tiếng Việt

Build pub package <a href="https://discord.gg/GSt793j6eT"><img src="https://img.shields.io/discord/765557403865186374.svg?logo=discord&color=blue" alt="Discord"></a>

<img src="https://raw.githubusercontent.com/rrousselGit/provider/master/resources/flutter_favorite.png" width="200" />

Welcome to [Freezed], yet another code generator for data classes, tagged unions, nested classes and cloning.

Migration to 3.0.0

To migrate from 2.0.0 to 3.0.0, see changelog and our migration guide.

Motivation

Dart is awesome, but defining a "model" can be tedious. You have to:

  • Define a constructor + properties
  • Override toString, operator ==, hashCode
  • Implement a copyWith method to clone the object
  • Handle (de)serialization

Implementing all of this can take hundreds of lines, which are error-prone and affect the readability of your model significantly.

Freezed tries to fix that by implementing most of this for you, allowing you to focus on the definition of your model.

| Before | After | | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | before | before |

Index

How to use

Install

To use [Freezed], you will need your typical [build_runner]/code-generator setup.
First, install [build_runner] and [Freezed] by adding them to your pubspec.yaml file:

For a Flutter project:

flutter pub add \
  dev:build_runner \
  freezed_annotation \
  dev:freezed
# if using freezed to generate fromJson/toJson, also add:
flutter pub add json_annotation dev:json_serializable

For a Dart project:

dart pub add \
  dev:build_runner \
  freezed_annotation \
  dev:freezed
# if using freezed to generate fromJson/toJson, also add:
dart pub add json_annotation dev:json_serializable

This installs three packages:

Disabling invalid_annotation_target warning and warning in generates files

If you plan on using [Freezed] in combination with json_serializable, recent versions of json_serializable and meta may require you to disable the invalid_annotation_target warning.

To do that, you can add the following to the analysis_options.yaml file at the root of your project:

analyzer:
  errors:
    invalid_annotation_target: ignore

Run the generator

To run the code generator, execute the following command:

dart run build_runner watch -d

Note that like most code-generators, [Freezed] will need you to both import the annotation ([freezed_annotation]) and use the part keyword on the top of your files.

As such, a file that wants to use [Freezed] will start with:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'my_file.freezed.dart';

CONSIDER also importing package:flutter/foundation.dart.
The reason being, importing foundation.dart also imports classes to make an object nicely readable in Flutter's devtool.
If you import foundation.dart, [Freezed] will automatically do it for you.

Creating a Model using Freezed

Freezed offers two ways of creating data-classes:

Primary constructors

Freezed implements Primary Constructors by relying on factory constructors. The idea is, you define a factory and Freezed generates everything else:

import 'package:freezed_annotation/freezed_annotation.dart';

// required: associates our `main.dart` with the code generated by Freezed
part 'main.freezed.dart';
// optional: Since our Person class is serializable, we must add this line.
// But if Person was not serializable, we could skip it.
part 'main.g.dart';

@freezed
abstract class Person with _$Person {
  const factory Person({
    required String firstName,
    required String lastName,
    required int age,
  }) = _Person;

  factory Person.fromJson(Map<String, Object?> json) => _$PersonFromJson(json);
}

The following snippet defines a model named Person:

  • Person has 3 properties: firstName, lastName and age
  • Because we are using @freezed, all of this class's properties are immutable.
  • Since we defined a fromJson, this class is de/serializable. Freezed will add a toJson method for us.
  • Freezed will also automatically generate:
    • a copyWith method, for cloning the object with different properties
    • a toString override listing all the properties of the object
    • an operator == and hashCode override (since Person is immutable)

From this example, we can notice a few things:

  • It is necessary to annotate our model with @freezed (or @Freezed/@unfreezed, more about that later).
    This annotation is what tells Freezed to generate code for that class.

  • We must also apply a mixin with the name of our class, prefixed by _$. This mixin is what defines the various properties/methods of our object.

  • When defining a constructor in a Freezed class, we should use the factory keyword as showcased (const is optional).
    The parameters of this constructor will be the list of all properties that this class contains.
    Parameters don't have to be named and required. Feel free to use positional optional parameters if you want!

Adding getters and methods to our models

Sometimes, you may want to manually define methods/properties in our classes.
But you will quickly notice that if you try to use primary constructors:

@freezed
abstract class Person with _$Person {
  const factory Person(String name, {int? age}) = _Person;

  void method() {
    print('hello world');
  }
}

then it will fail with

View on GitHub
GitHub Stars2.2k
CategoryDevelopment
Updated5d ago
Forks298

Languages

Dart

Security Score

85/100

Audited on Mar 28, 2026

No findings