Make changes to your app's default behavior and appearance by changing parameter values — just like Firebase Remote Config, but locally. It’s designed for teams that need flexibility to override parameters, test feature flags, and simulate Remote Config behavior directly on their devices.
The main goal is to provide the ability to manage configs locally for any purpose during development, testing, and even staging workflows.
- Familiar API inspired by Firebase Remote Config (
onConfigUpdated,getBool,getString, etc) - Built-in widget, also inspired by Firebase Remote Config, for viewing/editing parameter values
- Persistent parameter value overrides using
shared_preferencesorflutter_secure_storage
dependencies:
local_config: ^0.2.3import 'package:flutter/material.dart';
import 'package:local_config/local_config.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LocalConfig.instance.initialize(
params: {
'social_login_enabled': false,
'timeout_ms': 8000,
'animation_speed': 1.25,
'api_base_url': 'https://api.myapp.com/v1',
"checkout": {
"payment_methods": {
"allowed": ["credit_card", "pix", "boleto"],
"default": "credit_card",
},
"installments": {
"enabled": false,
"rules": [
{"max_installments": 3, "min_order_value": 0},
{"max_installments": 6, "min_order_value": 100},
{"max_installments": 10, "min_order_value": 300},
],
},
},
},
);
runApp(const ExampleApp());
}import 'package:flutter/material.dart';
import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:local_config/local_config.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FirebaseRemoteConfig.instance.fetchAndActivate();
await LocalConfig.instance.initialize(
params: FirebaseRemoteConfig.instance.getAll().map(
(key, value) => MapEntry(key, value.asString()),
),
);
runApp(const ExampleApp());
}
⚠️ Warning: When usingRemoteConfigValue.asString()from the firebase_remote_config package, the returned value may not always match the expected logical type. For example, boolean values may sometimes come as numeric strings ("0"or"1") instead of"true"or"false".
IconButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LocalConfigEntrypoint(),
),
);
},
tooltip: 'Local Config',
icon: const Icon(Icons.settings),
)final socialLoginEnabled = LocalConfig.instance.getBool('social_login_enabled');
final timeoutMs = LocalConfig.instance.getInt('timeout_ms');
final animatinoSpeed = LocalConfig.instance.getDouble('animation_speed');
final apiBaseUrl = LocalConfig.instance.getString('api_base_url');
final checkout = LocalConfig.instance.getString('checkout');LocalConfig.instance.onConfigUpdated.listen((configs) {
print('Configs updated: $configs');
});For a full demo, check the example folder.
- Report issues or request features in the GitHub Issues
- Contributions are welcome! Feel free to open pull requests.