provide 1.0.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 89

NOTE 2019-02-21: There's a discussion in the Flutter community over the difference between this package, package:provider, and package:scoped_model. There is a possibility that (some) of these efforts will merge. Learn more in issue #3.

If you must choose a package today, it's safer to go with package:scoped_model than with this package.

Watch the issue above or follow Flutter's Twitter account for updates.

This package contains classes to allow the passing of data down the widget tree. It is designed as a replacement for ScopedModel that allows for more flexible handling of data types and data.

Key widgets and static methods #

  • Provide<T> - Widget used to obtain values from a ProviderNode higher up in the widget tree and rebuild on change. The Provide<T> widget should only be used with Streams or Listenables. Equivalent to ScopedModelDescendant in ScopedModel.

  • Provide.value<T> - Static method used to get a value from a ProviderNode using the BuildContext. This will not rebuild on change. Similar to manually writing a static .of() method for an InheritedWidget.

  •<T> - Static method used to get a Stream from a ProviderNode. Only works if either T is listenable, or if the Provider comes from a Stream.

  • Provider<T> - A class that returns a typed value on demand. Stored in a ProviderNode to allow retrieval using Provide.

  • ProviderNode - The equivalent of the ScopedModel widget. Contains Providers which can be found as an InheritedWidget.

Usage #

This is a simple example of a counter app:

/// A provide widget can rebuild on changes to any class that implements
/// the listenable interface.
/// Here, we mixin ChangeNotifier so we don't need to manage listeners
/// ourselves.
/// Extending ValueNotifier<int> would be another simple way to do this.
class Counter with ChangeNotifier {
  int _value;

  int get value => _value;


  void increment() {

/// CounterApp which obtains a counter from the widget tree and uses it.
class CounterApp extends StatelessWidget {
  // The widgets here get the value of Counter in three different
  // ways.
  // - Provide<Counter> creates a widget that rebuilds on change
  // - Provide.value<Counter> obtains the value directly
  // -<Counter> returns a stream
  Widget build(BuildContext context) {
    // Gets the Counter from the nearest ProviderNode that contains a Counter.
    // This does not cause this widget to rebuild when the counter changes.
    final currentCounter = Provide.value<Counter>(context);

    return Column(children: [
      // Simplest way to retrieve the provided value.
      // Each time the counter changes, this will get rebuilt. This widget
      // requires the value to be a Listenable or a Stream. Otherwise
        builder: (context, child, counter) => Text('${counter.value}'),

      // This widget gets the counter as a stream of changes.
      // The stream is filtered so that this only rebuilds on even numbers.
          initialData: currentCounter,
              .where((counter) => counter.value % 2 == 0),
          builder: (context, snapshot) =>
              Text('Last even value: ${}')),

      // This button just needs to call a method on Counter. No need to rebuild
      // it as the value of Counter changes. Therefore, we can use the value of
      // `Provide.value<Counter>` from above.
      FlatButton(child: Text('increment'), onPressed: currentCounter.increment),

      Text('Another widget that does not depend on the Counter'),

void main() {
    // The class that contains all the providers. This shouldn't change after
    // being used.
    // In this case, the Counter gets instantiated the first time someone uses
    // it, and lives as a singleton after that.
    final providers = Providers()
      ..provide(Provider.function((context) => Counter(0)));

      providers: providers,
      child: CounterApp(),

How it works #

Similar to ScopedModel, this relies on InheritedWidgets in order to propagate data up and down the widget tree. However, unlike ScopedModel, rather than storing a single concrete type, a ProviderNode contains a map of Types to Providers. This means that a single node can contain any number of providers, and that a provider of a type doesn't have to be of the exact concrete type.

Somewhere in the tree, there is a ProviderNode, which contains a set of Providers. When a Provide widget is created, it searches up the widget tree for a ProviderNode that contains a provider for its requested type. It then listens for any changes to that requested type.

There are also static methods that operate on BuildContext that allow any widget's build function to get data from ProviderNodes without listening to changes directly.

Useful widgets to use with Provider #

  • ChangeNotifier — Easy way to implement Listenable. The equivalent of Model from ScopedModel.

  • ValueNotifier — Wrapping your mutable state in ValueNotifier<T> can save you from missing notifyListener calls.

  • StreamBuilder — Can be used with to have widgets that rebuild on stream changes.

1.0.2 #

  • Update README with a note about package:provider and package:scoped_model

1.0.1 #

  • Added example/ with CI testing
  • Added a CHANGELOG
  • Updates to README

1.0.0 #

  • Initial public release


// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:provide/provide.dart';

void main() {
  // Initialize the model. Can be done outside a widget, like here.
  var counter = Counter();

  // Here we set up a delayed interaction with the model (increment each
  // 5 seconds), outside of the Flutter widget tree.
  // This is just an example. In a real world app, this could be replaced
  // with a connection to a real-time database, for example.
    const Duration(seconds: 5),
    (timer) => counter.increment(),

  // Set up a Providers instance.
  var providers = Providers();

  // Now we're ready to run the app...
    // ... and provide the model to all widgets within.
      providers: providers,
      child: MyApp(),

/// Simplest possible model, with just one field.
class Counter extends ChangeNotifier {
  int value = 0;

  void increment() {
    value += 1;

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      home: MyHomePage(),

class MyHomePage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      body: Center(
        child: Column(
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            // Provide looks for an ancestor ProviderNode widget
            // and retrieves its model (Counter, in this case).
            // Then it uses that model to build widgets, and will trigger
            // rebuilds if the model is updated.
              builder: (context, child, counter) => Text(
                    style: Theme.of(context).textTheme.display1,
      floatingActionButton: FloatingActionButton(
        // Provide.value is another way to access the model object held
        // by an ancestor ProviderNode. By default, it just returns
        // the current model and doesn't automatically trigger rebuilds.
        // Since this button always looks the same, though, no rebuilds
        // are needed.
        onPressed: () => Provide.value<Counter>(context).increment(),
        tooltip: 'Increment',
        child: Icon(Icons.add),

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  provide: ^1.0.2

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:provide/provide.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Jun 5, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.2
  • pana: 0.13.8-dev
  • Flutter: 1.17.1

Health suggestions

Fix lib/provide.dart. (-0.50 points)

Analysis of lib/provide.dart reported 1 hint:

line 570 col 28: 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Maintenance suggestions

Package is getting outdated. (-28.22 points)

The package was last published 66 weeks ago.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
mockito any
scoped_model any
test >=0.12.30+3