FS.FluentUI- A New F# UI Library

Andrew Sutton
4 min readDec 10, 2023

--

Using component/ UI libraries when developing web applications can make for a better looking and more optimized product while also saving massive amounts of development time (and heartache). Unfortunately, because of the niche-ness of F#, there aren’t a whole lot of options to choose from when it comes to robust component libraries.

Enter: FS.FluentUI- Version 9 of Microsoft’s FluentUI (React) made for F# in the style of Feliz. Some of the features that makes FluentUI such a powerhouse of a library, as Paul Gildea discusses, are its performance, the reduced amount of DOM elements, its accessibility, and an amazing amount of customization options.

Components

Even though Microsoft is updating and rolling out components at a steady pace, there are currently 60+ stable components that are available through FS.FluentUI, not to mention many other utilities/ functions. The Wiki is kept updated and has real-world code examples for just about every component/ utility available. From a Checkbox all the way to a DataGrid, if you can think of it, chances are you’ll find it — and because everything is written in the style of Feliz, you’ll enjoy using it.

Getting Started

It’s recommended that you use Femto to download FS.FluentUI because it will automatically detect the package manager you are using and bring in the required NPM packages for you. Otherwise, you can use paket (dotnet paket add FS.FluentUI — — project src/YourClientFolder.fsproj) or install it manually (dotnet add package FS.FluentUI — — project src/YourClientFolder.fsproj). The required NPM packages and their versions are listed in the fsproj.

To start using FS.FluentUI, you first need to wrap the upper-most element in a FluentProvider, which “transforms a passed theme to CSS variables and passes other settings to Fluent UI components”.

There are 5 pre-made themes to use, as well as 4 themes that are completely customizable. For example, if you wanted a dark theme but you didn’t want to use Microsoft’s default blue coloring, you can go to Microsoft’s Theme Designer, choose your “key color value”, click “Export”, then copy and paste the generated BrandVariants into your project. Because the brand variants are in Typescript and not F#, you’ll have to do a little converting (10: “#060201” -> ``10`` = “#060201”), but after you take care of the compilation errors, you’re good to go! Then you can just fluentProvider.theme.createDarkTheme MyCustomBrandVariants .

Customizing with Slots / Intro to Icons

Slots are “parts [of components] that are designed to be modified or replaced”. In FS.FluentUI, almost every slot can be replaced with a ReactElement, or you can further customize the existing slot with a list of IReactProperty’s. For example, let’s say I want to use the Dropdown component, but I want the typical “expand icon” to be a large red airplane icon (for obvious reasons). With FS.FluentUI, it would look like this:

When referencing the Typescript documentation, the description for slots will look like this mess:

WithSlotShorthandValue<{ as?: “span”; } & Pick<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, “key” | keyof HTMLAttributes<…>> & { …; } & { …; }> | null

Thankfully, for us F#-ers, when we see that, all we have to think is “a ReactElement, a list of IReactProperties, or sometimes just a string”.

Side note: FluentUI has over 4,500 icons. One of the great parts about using F# is that, instead of finding the name andimporting every one we want to use, all we have to do it Fui.icon. and we can search for what we want!

From Typescript -> F#

Let’s take a real-life example from the Microsoft docs and translate it into F#. This example will be more complex and will use “makeStyles” and “positioning” — both of which are important concepts in FluentUI:

Conclusion

My goal with FS.FluentUI is to help make the front end of F# look as good as the language is. With features like Design Tokens, Bundle Icons, Positioning, and many, many more, I have a feeling FluentUI is here to stay, and I’m glad I can help bring it into the F# world.

--

--