Flutter can draw an SVG through the flutter_svg package or through a CustomPainter generated from the path data. They look similar on screen, but they have different costs: one adds a dependency and keeps the SVG file; the other adds generated Dart code and gives you the Path directly.
The Dart examples were checked with Flutter 3.47.9 / Dart 3.13.7 and flutter_svg 2.1.0. The SvgPicture.string widget test and the CustomPainter paint test pass flutter test.
Choose by what you need to change
| Need | Use |
|---|---|
| Display many SVG files as they are | flutter_svg |
| No extra package, or a small fixed icon set | Generated CustomPainter |
| Animate or change individual paths | Generated CustomPainter |
| Clip or hit-test with the shape | Generated CustomPainter |
| Text, gradients, filters or complex SVG features | flutter_svg, after checking the file |
Option 1: flutter_svg
Add the package, put the file in assets/, and declare it in pubspec.yaml:
flutter pub add flutter_svg
# pubspec.yaml
flutter:
assets:
- assets/icons/Then render it like any other widget:
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CheckIcon extends StatelessWidget {
const CheckIcon({super.key});
@override
Widget build(BuildContext context) {
return SvgPicture.asset(
'assets/icons/check.svg',
width: 24,
height: 24,
colorFilter: const ColorFilter.mode(Colors.black, BlendMode.srcIn),
);
}
}colorFilter replaces the rendered colour, which is useful for theme colours. It applies to the whole picture, so it cannot tint separate parts differently. The same widget works with SvgPicture.string(svgSource) for a string.
Option 2: generated CustomPainter
Paste the SVG into the SVG to Flutter converter. It produces a Path and a painter. A small painter looks like this:
import 'package:flutter/material.dart';
class IconPainter extends CustomPainter {
final Path path;
final Color color;
const IconPainter(this.path, {this.color = const Color(0xFF1E88E5)});
@override
void paint(Canvas canvas, Size size) {
final scale = size.width / 24;
canvas.scale(scale, scale);
canvas.drawPath(path, Paint()..color = color);
}
@override
bool shouldRepaint(covariant IconPainter oldDelegate) =>
oldDelegate.path != path || oldDelegate.color != color;
}Use it inside a sized box so the 24-unit viewBox scales correctly:
SizedBox(
width: 24,
height: 24,
child: CustomPaint(
painter: IconPainter(path),
),
)The converter handles paths, basic shapes, transforms and inherited styles. It skips text, gradients, patterns, <use>, images, masks, filters, markers and dashed strokes. The page lists every skipped feature, so check that list before replacing an existing SVG.
Colours are not the same format
Flutter uses Color(0xAARRGGBB), with alpha first. An SVG colour such as #1E88E5 becomes Color(0xFF1E88E5) when it is opaque. If the converter output has the wrong colour or alpha, use the Flutter Color converter to check the value.
When the SVG is not a good fit
- Text: convert text to paths in the editor first. Neither approach treats a font as a portable shape.
- Gradients: the painter falls back to a solid colour; a
Shadermust be added by hand. - Many changing icons:
flutter_svgis usually simpler than regenerating painters. - Animation: a painter gives you the
Pathand arepaintnotifier, but you still write the animation controller and interpolation.
Test the rendered result
A widget test can confirm the widget builds and paints without throwing:
testWidgets('renders the SVG icon', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SvgPicture.string(
svgSource,
width: 24,
height: 24,
),
),
),
);
expect(find.byType(SvgPicture), findsOneWidget);
});For a generated painter, draw it into a PictureRecorder and assert that painting completes; this catches malformed path data without needing a golden image:
test('paints the generated path', () {
final recorder = PictureRecorder();
final canvas = Canvas(recorder);
IconPainter(path).paint(canvas, const Size(24, 24));
recorder.endRecording().dispose();
});Start with the SVG converter
The SVG to Flutter converter shows the generated path, the painter and the skipped-feature list. If the file uses unsupported features, keep it as an asset with flutter_svg instead of rewriting the missing parts by hand. For the full comparison of Flutter drawing options, see the Flutter Color from hex guide and the Flutter JSON serialization guide.