AssetFlux Flutter SDK
Manage remote image assets in Flutter with automatic density selection, CDN caching, and gradual rollout support. Upload assets once via the AssetFlux dashboard and serve optimized variants to every device — no app update required.
- Drop-in
RemoteImagewidget — density- and format-aware, with shimmer placeholder - Offline-first — memory + disk cache with configurable TTL
- Gradual rollout — roll out new asset versions to a percentage of users
- Prefetch API — warm the cache before the UI needs it
Getting Started
1. Install
# pubspec.yaml
dependencies:
assetflux_flutter: ^1.0.0
flutter pub get
Android — add internet permission if not already present:
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET"/>
iOS — no additional setup required.
2. Initialize
import 'package:assetflux_flutter/assetflux_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AssetFlux.init(
projectId: 'af_...', // From AssetFlux dashboard → Settings → API Keys
apiKey: 'afk_...', // Use an SDK key (afk_ prefix)
);
runApp(const MyApp());
}
3. Display a Remote Asset
RemoteImage('home.hero.banner')
That's it. The SDK automatically selects the right density (1x / 2x / 3x), picks the best format (WebP > PNG), caches the result, and shows a shimmer while loading.
Usage
RemoteImage Widget
// Basic
RemoteImage('home.hero.banner')
// With placeholder, error handling, and sizing
RemoteImage(
'home.hero.banner',
placeholder: const ShimmerPlaceholder(),
errorWidget: const Icon(Icons.broken_image),
fallbackAsset: 'assets/images/default_banner.png',
width: double.infinity,
height: 200,
fit: BoxFit.cover,
)
Prefetch
Warm the cache before the UI renders:
// Single asset
await AssetFlux.prefetch('home.hero.banner');
// Multiple assets
await AssetFlux.prefetchAll(['home.logo', 'home.banner', 'profile.avatar']);
// Glob pattern
await AssetFlux.prefetchPattern('home.*');
Direct URL Resolution
Use resolveAssetUrl when you need the URL for a custom widget or download:
final url = AssetFlux.resolveAssetUrl(assetKey: 'home.banner');
Debug Info
Inspect how an asset resolves — version, rollout bucket, selected density:
final info = AssetFlux.getDebugInfo('home.banner');
// {found: true, version: 2, bucket: 37, inRollout: true, targetDensity: 2.0, ...}
Configuration
All options have sensible defaults. Override only what you need:
await AssetFlux.init(
projectId: 'af_...',
apiKey: 'afk_...',
config: const AssetFluxConfig(
cacheTTL: Duration(hours: 24), // Manifest cache lifetime
refreshInterval: Duration(minutes: 15), // Background refresh interval
timeout: Duration(seconds: 10), // Network request timeout
retryAttempts: 3, // Retries with exponential backoff
fallbackBehavior: FallbackMode.cacheFirst,
identifierType: IdentifierType.device,
debug: false,
),
);
| Option | Type | Default | Description |
|---|---|---|---|
cacheTTL |
Duration |
24 h | How long the cached manifest is considered fresh |
refreshInterval |
Duration |
15 min | Background manifest refresh interval |
timeout |
Duration |
10 s | Network request timeout |
retryAttempts |
int |
3 | Max retries with exponential backoff |
fallbackBehavior |
FallbackMode |
cacheFirst |
What to do when offline (see below) |
identifierType |
IdentifierType |
device |
Identifier source for rollout buckets |
customIdentifier |
String? |
null |
Value used when identifierType is custom |
instanceConfig |
InstanceConfig? |
null |
Custom API base URL (defaults to https://api.assetflux.io) |
debug |
bool |
false |
Print detailed logs to the console |
Fallback Modes
| Mode | Behavior |
|---|---|
cacheFirst |
Serve stale cache when offline. Error only if no cache exists. (default) |
bundled |
Fall back to a bundled asset (fallbackAsset on RemoteImage). |
placeholder |
Show an error widget when remote + cache both fail. |
Gradual Rollout
Roll out a new version of an asset to a percentage of users. Each device (or user) is deterministically assigned to a bucket (0–99) so they always see the same version.
// Device-based (default) — same device always sees same version
AssetFluxConfig(identifierType: IdentifierType.device)
// User-based — same user across devices
AssetFluxConfig(identifierType: IdentifierType.user)
// then after login:
AssetFlux.setUserId('user_12345');
// Custom — e.g. organization, A/B test group
AssetFluxConfig(
identifierType: IdentifierType.custom,
customIdentifier: 'org_abc',
)
Rollout percentages are configured in the AssetFlux dashboard, not in client code.
Reactive Rebuilds
RemoteImage rebuilds automatically when the manifest updates. For custom widgets, listen to the notifier:
ValueListenableBuilder(
valueListenable: AssetFlux.manifestNotifier,
builder: (context, _, child) {
final url = AssetFlux.resolveAssetUrl(assetKey: 'home.banner');
return Image.network(url ?? '');
},
)
Requirements
| Minimum | |
|---|---|
| Flutter | 3.0 |
| Dart | 3.0 |
| iOS | 12.0 |
| Android | API 21 |
Documentation
Full documentation is available at docs.assetflux.io/flutter.
License
BSD 3-Clause. See LICENSE for details.
Libraries
- assetflux_flutter
- AssetFlux Flutter SDK