Pro Every tool, icon and stickerAll of Pro for $7.99/month

  • All 90 tools
  • Every icon style
  • Icon & sticker pack ZIPs
Go Pro
HubToolify

Flutter

An HtiIcon widget and one constant per icon for Flutter apps on Android, iOS, web and desktop, themed like Icon.

as Markdown, for notes or an AI chat

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.

Terminal
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.

Dart
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.

Dart
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:

Dart
IconTheme(
  data: const IconThemeData(size: 20, color: Color(0xFF1766F2)),
  child: Row(children: const [HtiIcon(HtiIcons.home), HtiIcon(HtiIcons.search)]),
)

Properties#

PropertyValue
iconAn HtiIcons constant. null keeps the space and draws nothing
sizeWidth and height in logical pixels. Default: the IconTheme size, then 24
colorDefault: the IconTheme colour, with its opacity applied
strokeWidthLine weight on the 24 px grid. Default 1.2
semanticLabelThe 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.

Dart
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:

Dart
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.

  1. Create a Flutter token on your Connected apps page.
  2. Give it to pub, once per computer:
Terminal
dart pub token add https://hubtoolify.com/api/pub
# paste the token when asked
  1. Add the package to pubspec.yaml and run flutter pub get:
pubspec.yaml
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.

Dart
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)
StyleImportClass
Solidsolid.dartHtiSolidIcons
Duotoneduotone.dartHtiDuotoneIcons
Sharp Linesharp_line.dartHtiSharpLineIcons
Sharp Solidsharp_solid.dartHtiSharpSolidIcons
Sharp Duotonesharp_duotone.dartHtiSharpDuotoneIcons
Imprintimprint.dartHtiImprintIcons
Pixelpixel.dartHtiPixelIcons
Slabslab.dartHtiSlabIcons
Mellowmellow.dartHtiMellowIcons
Jassjass.dartHtiJassIcons
Drawdraw.dartHtiDrawIcons
Lineallineal.dartHtiLinealIcons
Duoduo.dartHtiDuoIcons
Flatflat.dartHtiFlatIcons

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.

    Type to search every page. ↑ ↓ to move, Enter to open.