The most basic provider type for synchronous, immutable values. Use Provider when you have a value that never changes during the application's lifecycle.
Create a simple provider with the @riverpod annotation:
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'config.g.dart';
@riverpod
String appName(AppNameRef ref) {
return 'Riverpod Gen Shortcuts';
}
@riverpod
int maxRetries(MaxRetriesRef ref) {
return 3;
}Provide service instances to your application:
@riverpod
ApiService apiService(ApiServiceRef ref) {
return ApiService(
baseUrl: 'https://api.example.com',
timeout: Duration(seconds: 30),
);
}
@riverpod
UserRepository userRepository(UserRepositoryRef ref) {
final apiService = ref.watch(apiServiceProvider);
return UserRepository(apiService);
}Create providers that depend on other providers:
@riverpod
String welcomeMessage(WelcomeMessageRef ref) {
final appName = ref.watch(appNameProvider);
final user = ref.watch(currentUserProvider);
return 'Welcome to $appName, ${user.name}!';
}
@riverpod
bool isDarkMode(IsDarkModeRef ref) {
final settings = ref.watch(appSettingsProvider);
return settings.theme == AppTheme.dark;
}Access provider values in your widgets:
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final appName = ref.watch(appNameProvider);
final welcomeMsg = ref.watch(welcomeMessageProvider);
return Column(
children: [
Text(appName, style: Theme.of(context).textTheme.headlineMedium),
Text(welcomeMsg),
],
);
}
}Prevent provider disposal:
@Riverpod(keepAlive: true)
ExpensiveService expensiveService(ExpensiveServiceRef ref) {
// This provider will never be disposed
return ExpensiveService();
}Explicitly declare provider dependencies:
@Riverpod(dependencies: [apiServiceProvider, configProvider])
DataRepository dataRepository(DataRepositoryRef ref) {
final api = ref.watch(apiServiceProvider);
final config = ref.watch(configProvider);
return DataRepository(api, config);
}@riverpod
AppConfig appConfig(AppConfigRef ref) {
return AppConfig(
apiUrl: const String.fromEnvironment('API_URL',
defaultValue: 'https://api.example.com'
),
enableAnalytics: bool.fromEnvironment('ENABLE_ANALYTICS'),
debugMode: kDebugMode,
);
}@riverpod
ThemeData lightTheme(LightThemeRef ref) {
return ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.amber),
fontFamily: 'Iosevka',
);
}
@riverpod
ThemeData darkTheme(DarkThemeRef ref) {
return ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.amber,
brightness: Brightness.dark,
),
fontFamily: 'Iosevka',
);
}Ready for mutable state? Check out NotifierProvider for state that can change over time, or FutureProvider for asynchronous operations.