Skip to main content

Easily Use Icon Fonts in .NET MAUI with IconFont.Maui

·5 mins

If you’ve ever used icon fonts in a .NET MAUI app, you know the drill: find the Unicode codepoint for the icon you need, copy-paste a cryptic string like "\uF4DA" into your XAML, forget what it means two days later, and repeat. Not great for maintainability. And that’s if you even get the font registered correctly in the first place!

I wanted to make this better. So I built IconFont.Maui — a set of packages and a template repository that give you strongly-typed, IntelliSense-friendly glyph constants generated directly from your TTF files at compile time. No manual mapping, no copy-pasting Unicode values.

The Problem #

Using icon fonts in .NET MAUI typically means something like this:

<Label Text="&#xF52A;"
       FontFamily="BootstrapIcons" />

What icon is that? Good luck remembering. And if the font updates and codepoints shift? You’re in for a fun afternoon of fixing things.

What I wanted was something like this:

<Label Text="{x:Static icons:BootstrapIcons.Search}"
       FontFamily="{x:Static icons:BootstrapIcons.FontFamily}" />

Clear, discoverable, and if the font updates you just drop in the new TTF and rebuild. The source generator takes care of the rest.

How It Works #

At the core is IconFont.Maui.SourceGenerator, a Roslyn source generator that reads your TTF file’s OpenType tables (cmap and post) at compile time and emits a C# class with const string fields for every glyph. It also generates builder extension methods, font registration, and a FontFamily constant per class.

The key thing: this is a build-time only dependency. The source generator runs during compilation and the resulting NuGet package for your icon font has zero runtime dependency on it.

Here’s what the ecosystem looks like:

PackagePurpose
IconFont.Maui.SourceGeneratorThe shared source generator. Reference this to generate glyph constants from any TTF.
IconFont.Maui.TemplateTemplate repo — clone it, drop in your TTF, ship your own icon font package.
IconFont.Maui.FluentIconsReady-to-use package for Fluent UI System Icons.

Using an Existing Package #

If you just want to use Fluent Icons in your app, install the NuGet package:

dotnet add package IconFont.Maui.FluentIcons

Register the fonts in your MauiProgram.cs:

var builder = MauiApp.CreateBuilder()
    .UseMauiApp<App>()
    .UseIconFonts(); // registers all Fluent Icon font variations

Then use the icons in XAML:

xmlns:icons="clr-namespace:IconFont.Maui.FluentIcons;assembly=IconFont.Maui.FluentIcons"

<Image WidthRequest="24" HeightRequest="24">
    <Image.Source>
        <FontImageSource Glyph="{x:Static icons:FluentIconsRegular.Home24}"
                         FontFamily="{x:Static icons:FluentIconsRegular.FontFamily}"
                         Size="24" />
    </Image.Source>
</Image>

Or in C#:

var icon = new FontImageSource
{
    Glyph = FluentIconsFilled.Heart24,
    FontFamily = FluentIconsFilled.FontFamily,
    Size = 24,
    Color = Colors.Red
};

Each font variation gets its own class (FluentIconsRegular, FluentIconsFilled, FluentIconsLight, etc.) with its own FontFamily constant. No nested classes, no awkward XAML syntax — just ClassName.IconName.

Creating Your Own Icon Font Package #

This is where it gets fun. Want to ship your own icon font as a NuGet package? Clone the template:

git clone https://github.com/jfversluis/IconFont.Maui.Template.git MyAwesomeIcons

The template comes with everything pre-wired:

  1. Drop in your TTF — replace the sample font files in Resources/Fonts/
  2. Configure IconFont.props — tell the generator about your font:
<ItemGroup>
  <IconFontDefinition Include="Resources/Fonts/my-icons.ttf">
    <FontAlias>MyIcons</FontAlias>
    <FontClass>MyIcons</FontClass>
    <FontNamespace>MyCompany.Icons</FontNamespace>
  </IconFontDefinition>
</ItemGroup>
  1. Build — the source generator parses the TTF and emits all the glyph constants
  2. Ship it — the template includes CI/CD workflows for publishing to NuGet

That’s it. You now have a NuGet package with strongly-typed glyph constants, builder extensions, and automatic font registration. Your consumers just install the package, call .UseIconFonts(), and start using {x:Static} references in their XAML. They never need to know about the source generator — it’s not a runtime dependency of the resulting package.

Multi-Style Fonts #

Some icon fonts ship multiple styles. Fluent Icons, for example, has Regular, Filled, Light, and Resizable variations — each in their own TTF file. The source generator handles this by creating a separate class per font file:

  • FluentIconsRegular.Home24 / FluentIconsRegular.FontFamily
  • FluentIconsFilled.Home24 / FluentIconsFilled.FontFamily
  • FluentIconsLight.Home24 / FluentIconsLight.FontFamily

If your TTF contains mixed styles (like glyphs with both _regular and _filled suffixes), the generator splits them into separate classes automatically. Pretty neat.

How It Differs from Manual Approaches #

You might be thinking: “Can’t I just write a script to parse the font and generate a C# file?” Sure, you can. But here’s why the source generator approach is better:

  • Always in sync: The constants are generated from the TTF at every build. Update the font, rebuild, done.
  • No checked-in generated code: The glyph constants aren’t in your source tree. They’re generated in the obj/ folder during compilation.
  • Shared infrastructure: Every icon font package uses the same source generator. No code duplication across repos.
  • const string values: These work with {x:Static} in XAML, which requires compile-time constants. A static readonly field won’t cut it.

What’s Next #

I have a couple of improvements planned:

  • Convention over configuration (#1): Make IconFont.props optional for simple scenarios by automatically deriving font metadata from MauiFont items. This would reduce setup to literally two lines in your csproj.
  • Missing initializer warning (#2): A Roslyn analyzer that warns you at compile time if you reference icon glyphs but forgot to call .UseIconFonts() on your MauiAppBuilder.

Get Started #

Everything is open source and available now:

If you have a favorite icon font that you’d like to see as a package, clone the template and give it a shot. I’d love to see what you build with it!