Provider State Management in Flutter: (With Real-World Example)
Learn how to use Provider for state management in Flutter with examples, best practices, and advanced tips. Ideal for all experience levels
Provider State Management in Flutter: (With Real-World Example)
“What is the best way to manage state in Flutter?” If you’ve asked this question, you’re not alone. And the answer is: Provider.
In this article, we’ll dive into Provider in Flutter — what it is, how to use it, and when to use it. Whether you’re a beginner building your first Flutter app or an experienced dev managing complex architectures, this guide is for you.
We will also cover one real-world example in this article. So, let’s read it and learn it. :)

Master in Using Provider State Management in Flutter. What is Provider state management in flutter?
🚀 What is Provider in Flutter?
Provider is one of the most popular state management solutions in Flutter. It was developed by the Flutter team and is built on top of InheritedWidget, offering a more scalable and cleaner way to manage and share state across your widget tree.
It simplifies state sharing without the boilerplate or complexity of manual state lifts. Think of it as a wrapper that gives your widgets access to shared data in a reactive way.
When to Use Provider State Management in Flutter? Click this link to discover the Best Use Cases and Learn How to choose the Right Solution for your Flutter Project.
🔍 Why Use Provider for State Management?
- 🔄 Reactive UI: When your model changes, the UI updates automatically.
- 🧼 Clean Code: Keep business logic separate from UI widgets.
- ♻️ Scalable: Works well for both small and large Flutter apps.
- 💪 Strong Community: It’s well-documented and widely adopted.
💡 Did you know? The flutter provider state management package is so widely used, it’s often a beginner’s first introduction to state management in Flutter.
📦 Installing Provider in Flutter
Add the package to your pubspec.yaml:
dependencies:
provider: latest version
Then run:
flutter pub get
🧑💻 Flutter Provider Example (2025)
Let’s walk through A Real-World Example: The Smart Dark Mode Toggle
One of the most common features in modern apps is letting users switch between a light and dark theme. This is a perfect scenario to see why Provider is so powerful.
The Problem: How do you tell the entire app to change its theme when a single switch is flipped on a settings screen? Without a proper state management tool, this can get messy, involving complex callbacks or passing state down through many layers of widgets.
The Provider Solution: Using Provider, this becomes incredibly clean. We’ll do it in three simple, logical steps.
Step 1: Create the “State” Model (ChangeNotifier)
First, we define our app’s state. In this case, it’s just the current theme preference. We create a simple class that holds this data and includes a method to change it. This class uses ChangeNotifier to "notify" any listening widgets about the change.
Create a new file theme_provider.dart:
import 'package:flutter/material.dart';
// Our state model
class ThemeProvider with ChangeNotifier {
ThemeMode _themeMode = ThemeMode.light;
// Getter to access the current theme mode
ThemeMode get currentTheme => _themeMode;
// Method to toggle the theme and notify listeners
void toggleTheme() {
_themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
notifyListeners(); // This is the crucial part!
}
}
Step 2: “Provide” the State to the App (Top Level)
Next, we make our ThemeProvider available to the entire app. We do this at the very top of our widget tree, usually inmain.dart, by wrapping our main widget with ChangeNotifierProvider.
In main.dart:
import 'package:flutter/material.dart';
import 'package.provider/provider.dart';
import 'theme_provider.dart'; // Import the new file
import 'home_screen.dart'; // Your app's home screen
void main() {
runApp(
// Provide the ThemeProvider to the entire widget tree
ChangeNotifierProvider(
create: (context) => ThemeProvider(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// Use a Consumer to listen for changes in ThemeProvider
return Consumer<ThemeProvider>(
builder: (context, themeProvider, child) {
return MaterialApp(
title: 'Provider Demo',
themeMode: themeProvider.currentTheme, // Reacts to changes
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
home: const HomeScreen(),
);
},
);
}
}
Step 3: Consume the State(Model) in Widgets(UI)
Now, any widget can listen to ThemeProvider and react. Let's create a HomeScreen with a simple button in the AppBar to toggle the theme. We'll use Provider.of to call the toggleTheme method.
Create a new file home_screen.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'theme_provider.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
// Access the provider to call its methods
final themeProvider = Provider.of<ThemeProvider>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: const Text("Provider is Smart!"),
actions: [
IconButton(
icon: const Icon(Icons.brightness_6_outlined),
onPressed: () {
// A simple, clean call to our business logic
themeProvider.toggleTheme();
},
),
],
),
body: const Center(
child: Text(
"Toggle the theme to see the magic!",
style: TextStyle(fontSize: 18),
),
),
);
}
}
A quick note on listen: falseIn the onPressed callback, we set it listen: false because this specific one IconButton doesn't need to be rebuilt when the theme changes. We are only using the provider to call a method. The MaterialApp, wrapped in the Consumer, is the widget that will actually rebuild to apply the new theme. This is a key optimization technique.
Why This is the Smart Way
This example is powerful because it perfectly demonstrates the Provider’s core benefits:
- Decoupling: Your UI (
HomeScreen) is completely separate from your business logic (ThemeProvider). The UI simply requests a change, and the logic handles it. - Efficiency: Provider intelligently rebuilds only the necessary widgets. Here, only the
MaterialApprebuilds because it's the one "consuming" the theme state. - Readability: The code is clean and the flow of data is easy to follow. Anyone reading your code can understand how the state is created, provided, and consumed.
🧱 What is MultiProvider in Flutter?
As your app grows, you’ll need more than one provider. That’s where MultiProvider comes in.
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CounterModel()),
ChangeNotifierProvider(create: (_) => AuthModel()),
],
child: MyApp(),
)
This is crucial when using provider in large apps. It keeps everything manageable and modular.
✅ Tip: Always place providers as high in the widget tree as needed, but no higher than necessary.
🧠 Best Practices for Provider State Management Flutter
- Use
ChangeNotifierfor simple reactive models - Never mutate state directly without calling
notifyListeners() - Avoid business logic in UI — delegate to models
- Use
ConsumerorSelectorwidgets wisely to avoid unnecessary rebuilds - Use
readvswatch:
context.read<T>()– one-time use (like on button press)context.watch<T>()– subscribe to changes (UI rebuilds)
- Use MultiProvider for a modular app structure
⚙️ Provider vs Riverpod: What’s the Difference?

Difference between Provider vs Riverpod.
Both are solid choices. Start with Provider, and move to Riverpod if your app grows in complexity.
🌐 Common Use Cases of Provider in Flutter
- Authentication state
- Shopping cart updates
- Theme switching (dark/light)
- Network data fetching
- Global UI state (e.g., language, currency)
🧪 Advanced: Selector vs Consumer
If you want to optimize performance:
- Use
ConsumerWhen you want a widget to rebuild on any model change. - Use
SelectorWhen you want to listen to a specific field, preventing unnecessary rebuilds.
Selector<CounterModel, int>(
selector: (_, model) => model.count,
builder: (_, count, __) => Text('$count'),
)
🎯 Final Thoughts
If you’re building apps with Flutter in 2025, learning provider Flutter state management is a must. It’s beginner-friendly, battle-tested, and extremely powerful for medium-sized apps.
Whether you’re following a Flutter provider tutorial, building a Flutter provider example, or wondering about state management in Flutter, Provider is a tool that grows with your project.
Ready to integrate Provider into your next project?
메타데이터
- post_id
- 3d902d91eb8a
- slug
- provider-state-management-in-flutter-with-real-world-example-3d902d91eb8a
- url
- https://medium.com/@tiger.chirag/provider-state-management-in-flutter-with-real-world-example-3d902d91eb8a
- canonical_url
- https://medium.com/@tiger.chirag/provider-state-management-in-flutter-with-real-world-example-3d902d91eb8a
- author_url
- https://medium.com/@tiger.chirag
- status
- ok
- fetched_at
- 2026-07-18 20:11:55