configwire_flutter
Flutter companion to the pure-Dart configwire client
(fetch, cache, typed getters, realtime).
One call supplies the two Flutter-specific pieces the pure-Dart client
cannot provide on its own: a SharedPreferencesAsync-backed CacheStore
and device-derived Targeting. Everything else behaves exactly as
documented in the configwire package.
Install
Once published:
flutter pub add configwire_flutter
Or pin it in your pubspec.yaml:
dependencies:
configwire_flutter: ^0.2.0
Then flutter pub get.
Usage
The snippet below matches example/main.dart. Copy, paste, run.
With no server running, the startup fetch fails gracefully and the demo
serves defaults. Point baseUrl at a real server to load the cache
plus force-fetch on startup.
import 'package:configwire_flutter/configwire_flutter.dart';
/// Offline-first demo: with no server running, the startup fetch fails
/// gracefully and the demo serves defaults. Point `baseUrl` at a real
/// server to load the cache plus force-fetch on startup.
Future<void> main() async {
final cw = ConfigWire(
apiKey: 'YOUR_SDK_KEY', // sent as X-ConfigWire-Key, never printed
env: 'dev',
baseUrl: 'http://127.0.0.1:8090',
defaults: {'launch_flag': false},
store: SharedPreferencesCacheStore(env: 'dev'),
);
await cw.configureFlutter(
customAttrs: {'plan': 'pro'},
);
await cw.ensureInitialized();
assert(cw.getBool('launch_flag') == false);
// NOTE: values printed, apiKey never printed.
// ignore: avoid_print
print(
'launch_flag=${cw.getBool('launch_flag')} targeting=${cw.targeting}',
);
await cw.dispose();
}
cw.configureFlutterwires Flutter-side targeting onto your ownconfigwireConfigWire. (ConfigWireFlutter.createConfigWireis deprecated — constructConfigWiredirectly and callcw.configureFlutterinstead.) Read more in theconfigwirepackage: reading values, variants, fetch lifecycle, realtime, analytics, logging, and cache.
Targeting
Targeting attributes are sent as fetch query params so the server can
evaluate rules per fetch. Collection is automatic
(package_info_plus; locale needs no extra dependency).
Targeting stays sticky through
cw.setTargeting / cw.updateTargeting exactly as in configwire.
Default targeting (every fetch carries these unless empty, in which case the param is omitted):
| Field | Query param | Default value | Source |
|---|---|---|---|
userId |
?userHash= |
Stable install ID: a 15-char lowercase [a-z0-9] ID, generated once and persisted, emitted as ?userHash=<sha256hex16> at fetch time. Customize the first-run value only via idGenerator (default defaultIdGenerator); '' stays anonymous and pins nothing |
SharedPreferencesAsync (+ idGenerator) |
platform |
?platform= |
android | ios | macos | windows | linux | fuchsia | web (kIsWeb forces web) |
defaultTargetPlatform |
appVersion |
?appVersion= |
Package version with +build metadata stripped for strict-semver compare (e.g. 1.0.0+1 → 1.0.0); empty (omitted) when unreadable |
package_info_plus |
locale |
?locale= |
toLanguageTag (e.g. en-US); empty (omitted) when unreadable |
PlatformDispatcher.locale |
country |
?country= |
countryCode (e.g. US); empty (omitted) when absent or unreadable |
PlatformDispatcher.locale |
customAttrs |
?attrs= (compact JSON) |
{} (omitted) unless passed via cw.configureFlutter(customAttrs:) |
Caller input |
License
MIT — Copyright (c) 2026 Lam Thanh Nhan. See LICENSE.