Package selection guidance compiled from public package information, community data, and project usage.
Flutter Data provides a streamlined approach to managing persistent data models in Flutter applications, drawing inspiration from Ember Data and ActiveRecord. It simplifies CRUD operations, state management, and data synchronization across devices by offering a unified API for working with local and remote data sources. The package integrates seamlessly with Flutter's ecosystem, supporting type-safe models, automatic serialization, and built-in caching. Developers can easily define data models and relationships, enabling efficient data handling without boilerplate code.
Use cases
Managing offline-first data workflows
Synchronizing data between local storage and APIs
Building scalable CRUD applications
Handling complex data relationships
Implementing reactive data updates
Key features
Automatic model serialization
Built-in persistence with SQLite
Reactive state management
Support for REST and GraphQL APIs
Type-safe data models and queries
Suitable for
Apps requiring offline data access
Projects using REST or GraphQL backends
Developers seeking reduced boilerplate
Teams adopting MVC-like data architecture
Applications with complex data relationships
Considerations
Learning curve for new users
Limited documentation compared to mature alternatives
May require additional setup for custom endpoints
Not ideal for very simple apps with minimal data needs
Depends on external dependencies like json_serializable
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
Flutter Data
Persistent reactive models in Flutter with zero boilerplate
Flutter Data is a local-first data framework with a customizable REST client and powerful model relationships, built on Riverpod.
In Flutter Data, every model gets its default adapter. These adapters can be extended by mixing in custom adapters.
Annotate a model with @DataAdapter and pass a custom adapter:
@JsonSerializable()
@DataAdapter([MyJSONServerAdapter])
classUserextendsDataModel<User> {
@overridefinalint? id; // ID can be of any typefinalString name;
User({this.id, requiredthis.name});
// `User.fromJson` and `toJson` optional
}
mixinMyJSONServerAdapteronRemoteAdapter<User> {
@overrideStringget baseUrl => "https://my-json-server.typicode.com/flutterdata/demo/";
}
After code-gen, Flutter Data will generate the resulting Adapter<User> which is accessible via Riverpod's ref.users or container.users.
@overrideWidgetbuild(BuildContext context, WidgetRef ref) {
final state = ref.users.watchOne(1);
if (state.isLoading) {
returnCenter(child: constCircularProgressIndicator());
}
final user = state.model;
returnText(user.name);
}
ref.users.watchOne(1) will make a background HTTP request (to https://my-json-server.typicode.com/flutterdata/demo/users/1 in this case), deserialize data and listen for any further local changes to the user.
state is of type DataState which has loading, error and data substates.
In addition to the reactivity, models have ActiveRecord-style extension methods so the above becomes:
Appwrite Offline. A Flutter Data adapter for Appwrite that provides offline support, real-time updates, and seamless integration with Flutter Data's powerful features.
🚨 BREAKING CHANGES IN 2.0
All methods are now directly on Adapter, there is no Repository, RemoteAdapter or LocalAdapter. Any method you are looking for is probably on Adapter, for example, findAll from LocalAdapter is now called findAllLocal
For initialization we no longer call the configure... method on the Riverpod overrides, we just do localStorageProvider.overrideWithValue and pass a LocalStorage instance; the actual initialization is done via initializeFlutterData which needs an adapter map. An adapterProvidersMap is conveniently code-generated and available on main.data.dart
Offline operations are still supported, but retries are not, it is up to clients to implement them
📚 Public API
Initialization
First you need to supply a local storage provider, via Riverpod configuration. A popular option for the base directory is using the path_provider package.