# Provider

Use when setting up providers, consuming state, optimizing rebuilds, using...

- Repository: https://github.com/evanca/flutter-ai-rules (668 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add evanca/flutter-ai-rules --skill provider -g -a claude-code -y`
Codex: `npx skills add evanca/flutter-ai-rules --skill provider -g -a codex -y`
Cursor: `npx skills add evanca/flutter-ai-rules --skill provider -g -a cursor -y`
Gemini CLI: `npx skills add evanca/flutter-ai-rules --skill provider -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add evanca/flutter-ai-rules`

## Description

Use when setting up providers, consuming state, optimizing rebuilds, using ProxyProvider, or migrating from deprecated providers (Provider package).

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Provider Skill

This skill defines how to correctly use the `provider` package in Flutter applications.

---

## 1. Provider Types

| Provider | Use for |
|---|---|
| `Provider` | Exposing any immutable value |
| `ChangeNotifierProvider` | Mutable state with `ChangeNotifier` |
| `FutureProvider` | Exposing a `Future` result |
| `StreamProvider` | Exposing a `Stream` |
| `ProxyProvider` / `ChangeNotifierProxyProvider` | Objects that depend on other providers |

---

## 2. Setup

```dart
MultiProvider(
  providers: [
    Provider<Something>(create: (_) => Something()),
    ChangeNotifierProvider(create: (_) => MyNotifier()),
    FutureProvider<String>(create: (_) => fetchData(), initialData: ''),
  ],
  child: MyApp(),
)
```

- Use `MultiProvider` to group multiple providers and avoid deeply nested trees.
- `ChangeNotifierProvider` **automatically disposes** the model when it is no longer needed.
- **Never** create a provider's object from variables that can change over time, the object won't update when the variable changes. Use `ProxyProvider` instead.
- If you have 150+ providers, consider mounting them over time (e.g., during a splash screen) rather than all at once to avoid `StackOverflowError`.

---

## 3. Consuming State

Always specify the **generic type** for type safety:

```dart
// Listen and rebuild on change, only valid inside build() or a Provider's update method
final count = context.watch<MyModel>().count;

// Access without listening, use in callbacks, not inside build()
context.read<MyModel>().increment();

// Listen to only part of the state
final count = context.select<MyModel, int>((m) => m.count);
```

Use `Consumer<T>` or `Selector<T, R>` widgets when you need fine-grained rebuilds and cannot access a descendant `BuildContext`:

```dart
Consumer<MyModel>(
  builder: (context, model, child) => Text('${model.count}'),
  child: const ExpensiveWidget(), // rebuilt only once
)

The rest: https://github.com/evanca/flutter-ai-rules/blob/HEAD/skills/provider/SKILL.md
