Flutter
An HtiIcon widget and one constant per icon for Flutter apps on Android, iOS, web and desktop, themed like Icon.
hubtoolify_icons brings every free icon to Flutter, in the Line style. Flutter draws each icon itself as vector paths, so icons stay sharp at any size on Android, iOS, web, Windows, macOS and Linux. The package needs no SVG plugin and no icon font, and has no dependencies besides Flutter.
Install#
The package needs Flutter 3.27 or later.
flutter pub add hubtoolify_icons
Use#
Each icon is a constant on HtiIcons, named after the icon in lowerCamelCase: arrow-up-right becomes HtiIcons.arrowUpRight and clock-1 becomes HtiIcons.clock1. A name that is a Dart keyword gets an Icon suffix, so case becomes HtiIcons.caseIcon. Find names in the icon library.
import 'package:hubtoolify_icons/hubtoolify_icons.dart';
const HtiIcon(HtiIcons.home)
HtiIcon(HtiIcons.calendarCheck, size: 32, color: Colors.indigo)
HtiIcon(HtiIcons.bell, strokeWidth: 1.8)
const HtiIcon(HtiIcons.heart, semanticLabel: 'Favourite')
With Material widgets#
HtiIcon works like Flutter's own Icon. It takes its size, colour and opacity from the nearest IconTheme, so in an AppBar, IconButton, ListTile or NavigationBar it gets the same colours as the Material icons around it, including the selected state.
AppBar(
leading: IconButton(icon: const HtiIcon(HtiIcons.menu), tooltip: 'Menu', onPressed: openDrawer),
actions: [
IconButton(icon: const HtiIcon(HtiIcons.search), tooltip: 'Search', onPressed: openSearch),
],
)
NavigationBar(destinations: const [
NavigationDestination(icon: HtiIcon(HtiIcons.home), label: 'Home'),
NavigationDestination(icon: HtiIcon(HtiIcons.settings), label: 'Settings'),
])
ListTile(leading: const HtiIcon(HtiIcons.bell), title: const Text('Notifications'))
To set the size or colour for a group of icons, wrap them in an IconTheme:
IconTheme(
data: const IconThemeData(size: 20, color: Color(0xFF1766F2)),
child: Row(children: const [HtiIcon(HtiIcons.home), HtiIcon(HtiIcons.search)]),
)
Properties#
| Property | Value |
|---|---|
icon | An HtiIcons constant. null keeps the space and draws nothing |
size | Width and height in logical pixels. Default: the IconTheme size, then 24 |
color | Default: the IconTheme colour, with its opacity applied |
strokeWidth | Line weight on the 24 px grid. Default 1.2 |
semanticLabel | The name screen readers announce. Without it the icon is decorative |
App size#
Each icon is a const, and a release build keeps only the constants your code uses. An app that uses ten icons ships ten icons. We checked this on a web release build: the icons the app did not use were not in the output.
If icon names reach your app as data, from a CMS or an API, look them up by name. The lookup map refers to every icon, so importing it puts all 4,309 icons in your app, about 1.4 MB of path data before compression.
import 'package:hubtoolify_icons/by_name.dart';
final icon = htiIconsByName['arrow-up-right']; // null if there is no such icon
HtiIcon(icon)
Drawing in a custom painter#
HtiIconPainter draws an icon at any size on a canvas you already have:
class BadgePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
canvas.drawCircle(size.center(Offset.zero), size.width / 2, Paint()..color = Colors.indigo);
canvas.save();
canvas.translate(size.width * .25, size.height * .25);
HtiIconPainter(icon: HtiIcons.star, color: Colors.white).paint(canvas, size / 2);
canvas.restore();
}
@override
bool shouldRepaint(BadgePainter oldDelegate) => false;
}
Accessibility#
Icons are decorative by default, and screen readers skip them. Give an icon a semanticLabel when it means something on its own, such as a status icon with no text next to it. For an icon-only button, give the button a tooltip or label and leave the icon unlabelled, so the screen reader reads it once.
Pro styles#
With a Pro plan, hubtoolify_icons_pro has every Pro vector style: Solid, Duotone, Sharp Line, Sharp Solid, Sharp Duotone, Imprint, Pixel, Slab, Mellow, Jass, Draw, Lineal, Duo and Flat. 3D icons are rendered images and come in the Pro download. The package installs from HubToolify's own package repository, not from pub.dev.
- Create a Flutter token on your Connected apps page.
- Give it to pub, once per computer:
dart pub token add https://hubtoolify.com/api/pub
# paste the token when asked
- Add the package to
pubspec.yamland runflutter pub get:
dependencies:
hubtoolify_icons_pro:
hosted: https://hubtoolify.com/api/pub
version: ^2.0.0
Each style is its own library, so an app compiles only the styles it imports and keeps only the icons it uses. HtiProIcon takes the same size, color and semanticLabel as HtiIcon. The two-tone styles also take secondaryColor and secondaryOpacity. Duo and Flat start in each icon's own colour until you pass color. Jass and Lineal keep their fixed palette.
import 'package:hubtoolify_icons_pro/slab.dart';
import 'package:hubtoolify_icons_pro/duotone.dart';
const HtiProIcon(HtiSlabIcons.home)
HtiProIcon(HtiDuotoneIcons.bell, size: 32, color: Colors.indigo, secondaryColor: Colors.amber)
| Style | Import | Class |
|---|---|---|
| Solid | solid.dart | HtiSolidIcons |
| Duotone | duotone.dart | HtiDuotoneIcons |
| Sharp Line | sharp_line.dart | HtiSharpLineIcons |
| Sharp Solid | sharp_solid.dart | HtiSharpSolidIcons |
| Sharp Duotone | sharp_duotone.dart | HtiSharpDuotoneIcons |
| Imprint | imprint.dart | HtiImprintIcons |
| Pixel | pixel.dart | HtiPixelIcons |
| Slab | slab.dart | HtiSlabIcons |
| Mellow | mellow.dart | HtiMellowIcons |
| Jass | jass.dart | HtiJassIcons |
| Draw | draw.dart | HtiDrawIcons |
| Lineal | lineal.dart | HtiLinealIcons |
| Duo | duo.dart | HtiDuoIcons |
| Flat | flat.dart | HtiFlatIcons |
In CI, keep the token in a secret and pass it through an environment variable: dart pub token add https://hubtoolify.com/api/pub --env-var HUBTOOLIFY_TOKEN. If your plan ends, the repository stops serving new installs and updates. The icons already in your apps keep working, and the pub cache keeps the package for flutter pub get --offline. See the licence.
© 2026 HubToolify. Documentation text and examples are HubToolify's own; code snippets may be copied into your projects.