The Big List of Haskell GUI Libraries

Posted on July 3, 2022
Last modified: July 25, 2022

(Note: this originated as a list I kept on reposting in response to repeated questions on /r/haskell, and more recently on the Discord FP server too. I figured it was finally time to give it a permanant home. I’ve also taken the opportunity to expand it out a little bit.)

Haskell has an excellent selection of GUI libraries, both for desktop and for web applications. However, choosing between them can be difficult. In practice I find the main differentiator to be ease of installation: some Haskell GUI libraries are notably difficult to install, but others are much easier to get working. They also differ strongly in look and feel, as well as in programming paradigm (imperative vs FRP vs Elm architecture). This article aims to list the GUI libraries available for Haskell and give an outline of their differences.

Recommendations: gi-gtk is probably the best all-round desktop GUI library for Haskell, if you can get it installed. If not, fltkhs and monomer should also work well. For more advanced usecases, Haskell backends can be linked to a frontend GUI written in C or C++. For web GUIs, try threepenny-gui, Miso or Reflex — the former is much easier to both use and install, but the latter two allow compilation to JavaScript via GHCJS.

Desktop GUI libraries

Probably the best all-round desktop GUI library for Haskell is gi-gtk, which provides Haskell bindings to the widely-used GTK+ library. gi-gtk is easy to use, and is documented fairly well by the official GTK+ documentation for C and other languages. The only major problem with gi-gtk is that it can be difficult to install on Windows, despite the existence of an installation guide. Additionally, GTK+ can look and feel conspicuously non-native, especially on Windows.

(Sometimes the older libraries gtk3 and gtk2hs are also mentioned. However, those are currently unmaintained, and gi-gtk should be used instead.)

Also worth mentioning are the two libraries gi-gtk-declarative and gi-gtk-declarative-app-simple. These are not standalone libraries, but build on gi-gtk to provide a less imperative interface. gi-gtk-declarative defines the underlying data structures and functions required to build a declarative GUI framework. One suce framework built on gi-gtk-declarative is gi-gtk-declarative-app-simple, which provides a simple declarative framework based on the Elm architecture. For smaller GUIs, gi-gtk-declarative-app-simple is thus very suitable. However, for more complex applications it can be easier to write a custom gi-gtk-declarative-based framework. Personally, I prefer to simply use gi-gtk directly, but others may prefer to use such a declarative framework.

As well as GTK+ bindings, there are Haskell bindings to FLTK, in the form of fltkhs. Unlike most of the other libraries mentioned here, fltkhs has very clear documentation for installation on all major platforms. It is also easy to use. Unfortunately, its looks are against it: though I regret to say it, I find FLTK to look extremely ugly by default. However, themes are available through the fltkhs-themes Haskell package.

Bindings to Qt also exist, via the Qtah project. Reportedly this works well, at least on Linux, and presumably on Mac OSX too. However, it currently does not support Windows. (In theory there is no reason why it should not work there; however, no-one has yet put in the time to fix this, though for almost a year now I have been meaning to look into it myself. I should get on to it…)

In addition to the major GUI libraries already listed, bindings to wxWidgets also exist, thanks to wxHaskell. Unfortunately, wxHaskell has been long unmaintained (no commits for 4 years as of the time of writing), and I’ve found it nearly impossible to install, at least on Windows. I have been informed that other people have had more success, but either way installation and usage seems to be extremely difficult with the current Haskell toolchain.

monomer is a more recent Haskell GUI library. It is unique in being a pure Haskell framework, though it uses bindings to SDL underlyingly. I have yet to use monomer myself, but it seems an excellent choice for GUIs which might otherwise be written with GTK+ or FLTK.

A somewhat different approach is provided by dear-imgui.hs. This library contains bindings to the Dear ImGui framework. As such, it inherits the usual advantages and disadvantages of immediate-mode GUIs (see e.g. https://news.ycombinator.com/item?id=19745809, https://stackoverflow.com/questions/47444189 for relevant discussion). Of interest is the fact that the immediate-mode paradigm seems on first glance to blend very well with Haskell’s usual style of functional programming, with the proviso that I have not tried ImGui myself.

Lower-level libraries are also available. The sdl2 library gives Haskell bindings to SDL, while a somewhat higher-level interface is provided by gloss. Both of these are general-purpose graphics libraries: they are intended for drawing arbitrary shapes on a window, rather than interactive GUIs. However, it is certainly possible to implement a GUI framework on top of these (as indeed monomer does) if no other ready-made library suits. This is the approach taken by many games.

Haskell also has mature bindings to the Win32 API, via the well-known Win32 library. These bindings allow the creation of native Windows GUIs, as described by numerous other tutorials (e.g. theForger’s). However, this approach is extremely painful for all but the very simplest of message boxes. There is no sense in using Win32 for GUI applications, unless for some reason it is absolutely vital to create a native Windows GUI in Haskell.

It is also possible to write the underlying logic in Haskell, but use some other language for the GUI. On Windows, I have had considerable success in linking a Haskell program to a GUI written in C++ using Qt; an outline of how this works is provided in the Brassica architectural overview. However, I have also heard that it is extremely difficult to get this approach working on Linux. The conversation starting at http://verduria.org/viewtopic.php?p=51303#p51303 may be of interest for the latter case.

A similar alternative is to convert a web-based GUI to a desktop application using Electron. This can easily be done using most, if not all of the web-based frameworks listed below. Electron has certain advantages, most notably the ease of cross-platform porting. As with other web-based approaches, it also allows great freedom in customising the look and feel of the resulting GUI, and provides access to the large Node.js ecosystem. However, I personally prefer to use one of the dedicated cross-platform GUI libraries already mentioned.

Web GUI libraries

In addition to the desktop-based GUI libraries already listed, Haskell has several libraries for creating web-based GUIs. Perhaps the easiest of these to install and use is threepenny-gui. This library creates native executables which run a small webserver, allowing a GUI to be displayed using a web browser. threepenny-gui also includes support for FRP, which can be very helpful for certain usecases. I have had success in using threepenny-gui for numerous different projects — often I use it to make an initial prototype GUI, which I can then rewrite using another library. As briefly mentioned above, it is also easily possible to use Electron to create desktop applications using threepenny-gui. A guide to writing Electon apps with threepenny-gui is available online.

Haskell can also be compiled to JavaScript using GHCJS. This is often desirable for applications which benefit from being easily accessible online. Unfortunately, despite this (quite significant) advantage, GHCJS itself is somewhat painful to use. Most prominently, GHCJS is difficult to install and use: in fact it is practically impossible to use GHCJS without the Nix package manager. (This is especially painful on Windows, though I find WSL works very well.) It also uses a significant amount of memory, and the applications it outputs can be much slower than those produced by GHC. However, GHCJS is still extremely useful in certain situations.

Several libraries are available for creating websites with GHCJS. Lowest-level are ghcjs-dom, jsaddle and ghcjs-base, which provide the basic interface for interacting with JavaScript and HTML from Haskell. (Some examples of their usage may be found at https://github.com/ghcjs/ghcjs-examples.) Notably, applications and frameworks which use jsaddle are compiler-agnostic: on GHCJS they produce a website, whereas on GHC they produce a small webserver as with threepenny-gui.

However, it is almost always easier to use a higher-level framework for GHCJS. By far the most prominent libraries in this space are Miso and Reflex. As both libraries are jsaddle-based, they may be used with both GHCJS and GHC — the latter mostly for development purposes, though.

Miso is based on virtual DOM diffing, allowing applications to be written with an Elm-like architecture. Miso has numerous advantages: most prominently, it is extremely fast and well-tested. Though I have not used Miso myself, it also seems much easier to understand and use than Reflex does. However, Miso is somewhat more difficult than Reflex to install and use.

By contrast to Miso, the Reflex library is based on FRP. (In fact, it is actually a fully general FRP library, but in practice it is almost always used with GHCJS via reflex-dom.) I have found Reflex somewhat inflexible and difficult to use, especially for very highly dynamic GUIs, as outlined in e.g. reflex-frp/reflex#461. Miso seems like it might cope better with such problems, though I have not yet used it myself. However, Reflex is much easier to install than Miso, thanks to the existence of projects such as Reflex Platform and Obelisk.

Other libraries

In addition to the libraries already mentioned, a number of niche or less actively developed GUI libraries are also available:

  • Fudgets is by far the oldest GUI library for Haskell, having been developed continuously since 1991 (before Haskell98!). It allows the creation of GUIs for the X window system using a unique GUI paradigm with some resemblance to FRP.
  • webviewhs contains bindings from Haskell to the webview library. However, it has seen no commits for three years as of the time of writing.
  • Momentu is a framework for animated desktop GUIs with responsive layout. It is currently actively used to create the interface for Lamdu. However, its documentation is extremely poor.
  • Concur is a framework for the creation of web-based GUIs. Its GUI model is advertised as combining FRP with the Elm architecture. However, Concur is no longer actively maintained and is not recommended for any new GUIs.
  • Shpadoinkle is another web-based GUI library, with similarities to Concur. Its maintenance status is unclear: no changes to the code have been made in over a year, but there is still some activity on the repository.