SVG Adaptive Loader
An adaptive bytes loader for Flutter that intelligently detects and loads .svg assets in both XML-based and binary compiled formats, making it perfect for optimized build pipelines.
Installation
Add the package to your pubspec.yaml:
dependencies :
leancode_flutter_svg_adaptive_loader : ^1.1.1
Import
import 'package:leancode_flutter_svg_adaptive_loader/leancode_flutter_svg_adaptive_loader.dart' ;
import 'package:flutter_svg/flutter_svg.dart' ;
Motivation
This package solves a specific problem in Flutter development:
The Problem:
XML-based SVG files are easy to maintain but slow to load
Compiled binary vectors (.svg.vec) are fast but not human-readable
You want to keep original SVGs in your repository
You want to compile them in CI/CD for release builds
You don’t want to change asset paths in code for different build types
The Solution: FlutterSvgAdaptiveLoader automatically detects the format and loads it appropriately, so you can:
Use XML SVGs in debug builds for easy development
Use compiled binary SVGs in release builds for performance
Keep the same .svg extension and asset paths in your code
How It Works
The loader examines the first 100 characters of the file to detect UTF-8 decoder replacement characters. If it finds invalid UTF-8 sequences, it treats the file as binary; otherwise, it processes it as XML.
// Automatically detects format
// - If XML: compiles to binary in memory
// - If binary: loads directly
SvgPicture ( FlutterSvgAdaptiveLoader ( 'assets/logo.svg' ))
Basic Usage
Simply pass a FlutterSvgAdaptiveLoader to SvgPicture:
SvgPicture (
FlutterSvgAdaptiveLoader ( 'assets/logo.svg' ),
width : 200 ,
height : 200 ,
)
With Custom Options
SvgPicture (
FlutterSvgAdaptiveLoader (
'assets/icon.svg' ,
packageName : 'my_package' ,
assetBundle : customBundle,
),
width : 48 ,
height : 48 ,
colorFilter : ColorFilter . mode (
Colors .blue,
BlendMode .srcIn,
),
)
Integration with flutter_gen
If you’re using flutter_gen for type-safe asset references, you can create an extension for even cleaner usage:
Create the extension file
adaptive_svg_extension.dart
import 'package:leancode_flutter_svg_adaptive_loader/leancode_flutter_svg_adaptive_loader.dart' ;
import 'package:flutter/widgets.dart' ;
import 'package:flutter_svg/flutter_svg.dart' ;
import 'package:your_app/gen/assets.gen.dart' ; // Your flutter_gen import
extension AdaptiveSvgGenImage on SvgGenImage {
SvgPicture adaptiveSvg ({
Key ? key,
bool matchTextDirection = false ,
AssetBundle ? bundle,
String ? package,
double ? width,
double ? height,
BoxFit fit = BoxFit .contain,
AlignmentGeometry alignment = Alignment .center,
bool allowDrawingOutsideViewBox = false ,
WidgetBuilder ? placeholderBuilder,
String ? semanticsLabel,
bool excludeFromSemantics = false ,
ColorFilter ? colorFilter,
Clip clipBehavior = Clip .hardEdge,
}) {
return SvgPicture (
FlutterSvgAdaptiveLoader (
path,
assetBundle : bundle,
packageName : package,
),
key : key,
matchTextDirection : matchTextDirection,
width : width,
height : height,
fit : fit,
alignment : alignment,
allowDrawingOutsideViewBox : allowDrawingOutsideViewBox,
placeholderBuilder : placeholderBuilder,
semanticsLabel : semanticsLabel,
excludeFromSemantics : excludeFromSemantics,
colorFilter : colorFilter,
clipBehavior : clipBehavior,
);
}
}
Use the extension
// Clean, type-safe usage
Assets .icons.logo. adaptiveSvg (
width : 200 ,
height : 200 ,
)
CI/CD Workflow Example
Here’s how to set up a build pipeline that compiles SVGs for release builds:
GitHub Actions
Shell Script
.github/workflows/build.yml
name : Build Release
on :
push :
branches : [ main ]
jobs :
build :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Setup Flutter
uses : subosito/flutter-action@v2
with :
flutter-version : '3.19.0'
- name : Install dependencies
run : flutter pub get
# Compile SVGs to binary format
- name : Compile SVG assets
run : |
flutter pub global activate vector_graphics_compiler
find assets -name "*.svg" -type f -exec sh -c '
vector_graphics_compiler "$1" "$1"
' _ {} \;
- name : Build APK
run : flutter build apk --release
#!/bin/bash
# Activate the vector graphics compiler
flutter pub global activate vector_graphics_compiler
# Find all SVG files and compile them
find assets -name "*.svg" -type f | while read svg_file ; do
echo "Compiling $svg_file "
vector_graphics_compiler " $svg_file " " $svg_file "
done
echo "SVG compilation complete!"
Make it executable: chmod +x scripts/compile_svgs.sh
Run before release builds: ./scripts/compile_svgs.sh
flutter build apk --release
Keep the .svg extension even for compiled vectors. This way, your code doesn’t need to change between debug and release builds.
Complete Example
import 'package:flutter/material.dart' ;
import 'package:flutter_svg/flutter_svg.dart' ;
import 'package:leancode_flutter_svg_adaptive_loader/leancode_flutter_svg_adaptive_loader.dart' ;
class LogoWidget extends StatelessWidget {
const LogoWidget ({ super .key});
@override
Widget build ( BuildContext context) {
return Center (
child : SvgPicture (
FlutterSvgAdaptiveLoader (
'assets/images/logo.svg' ,
),
width : 200 ,
height : 200 ,
placeholderBuilder : (context) => CircularProgressIndicator (),
semanticsLabel : 'App Logo' ,
),
);
}
}
API Reference
FlutterSvgAdaptiveLoader
class FlutterSvgAdaptiveLoader extends BytesLoader {
const FlutterSvgAdaptiveLoader (
String assetName, {
String ? packageName,
AssetBundle ? assetBundle,
});
}
Parameters:
assetName - The path to the SVG asset (e.g., 'assets/icon.svg')
packageName - Optional package name if loading from a package
assetBundle - Optional custom asset bundle (defaults to DefaultAssetBundle or rootBundle)
Advanced Configuration
Custom Asset Bundle
final customBundle = NetworkAssetBundle ( Uri . parse ( 'https://example.com' ));
SvgPicture (
FlutterSvgAdaptiveLoader (
'logo.svg' ,
assetBundle : customBundle,
),
)
Package Assets
When loading SVGs from a Flutter package:
SvgPicture (
FlutterSvgAdaptiveLoader (
'assets/icon.svg' ,
packageName : 'my_design_system' ,
),
)
XML SVG
Size: Larger (text format)
Load time: Slower (needs parsing & compilation)
Best for: Development, debugging
Human-readable: Yes
Binary Vector
Size: Smaller (binary format)
Load time: Faster (pre-compiled)
Best for: Production, release builds
Human-readable: No
Best Practices
Version control
Commit only XML SVGs to your repository. Keep them in version control for easy editing.
CI/CD compilation
Compile SVGs to binary format in your CI/CD pipeline for release builds.
Keep .svg extension
Don’t rename to .svg.vec - keep the .svg extension so your code works with both formats.
Test both formats
Verify that both XML and compiled formats work correctly during development.
Troubleshooting
SVG not loading
Make sure the asset is declared in pubspec.yaml:
flutter :
assets :
- assets/images/logo.svg
Compilation errors
If SVG compilation fails, check that:
The SVG file is valid XML
You have the latest vector_graphics_compiler
The SVG doesn’t use unsupported features
The loader checks the first 100 characters. If your SVG has unusual encoding or starts with many comments, it might misdetect. Keep SVG files clean and standard.
Source Code
View the source code on GitHub .