GitPedia

Keera hails

Keera Hails: Haskell on Rails - Reactive Programming Framework for Interactive Haskell applications

From keera-studios·Updated June 19, 2026·View on GitHub·

Keera Hails is a toolkit to create *Reactive Applications in Haskell*. It facilitates combining User Interfaces, external devices, network connections, files and, optionally, FRP networks. The project is written primarily in Haskell, distributed under the Other license, first published in 2012. Key topics include: android, frp, functional-reactive-programming, ghcjs, gtk.

Keera Hails

Build Status

Keera Hails is a toolkit to create Reactive Applications in Haskell.
It facilitates combining User Interfaces, external devices, network
connections, files and, optionally, FRP networks.

Keera Hails is modular and extensible. It is cross platform (Windows, Linux,
MacOSX, iOS, Android, GHCJS), UI-agnostic (Gtk+, WX, Qt, iOS native UIs,
Android Native toolkit, HTML DOM), FRP-agnostic and device-agnostic (Wiimote,
Webcams, etc).

Keera Hails has been used to create large applications and is used commercially
in production.

At a glance

<table> <tr> <td> <p align="center"> Keera Studios' Gale Studio! <br /><br /> <a href="http://keera.co.uk" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2011/10/Screenshot.png" height="auto" alt="Gale Studio screenshot" style="max-height:175px;"></a> <img width="441" height="1"> <br /> </p> </td> <td> <p align="center"> Guerric Chupin's Arpeggigon <br /><br /> <a href="https://gitlab.com/chupin/arpeggigon" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2020/05/arpeggigon.png" height="auto" alt="Arpeggigon screenshot" style="max-height:175px;"></a> <img width="441" height="1"> <br /> </p> </td> <td> <p align="center"> SoOSim simulator <br /> <br /> <img src="https://keera.co.uk/wp-content/uploads/2011/10/Screenshot-from-2014-09-24-142046.png" height="auto" alt="CAES group's SoOSim" style="max-height: 175px;"> <img width="441" height="1"> <br /> </p> </td> </tr> <tr> <td> <p align="center"> iOS demo <br /><br /> <a href="http://keera.co.uk" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2022/04/keera-hails-ios-demo-capture.gif" height="auto" alt="Keera Hails iOS demo app screenshot" style="max-height:175px;"></a> <img width="441" height="1"> <br /> </p> </td> <td> <p align="center"> Android demo <br /><br /> <a href="http://keera.co.uk" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2022/04/keera-hails-android-demo-capture.gif" height="auto" alt="Keera Hails Android demo app screenshot" style="max-height:175px;"></a> <img width="441" height="1"> <br /> </p> </td> <td> <p align="center"> Web demo <br /> <br /> <a href="http://keera.co.uk" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2022/04/hello-hails-web-calculator-css-final-orig-midres-short.gif" height="auto" alt="Keera Hails web demo app capture" style="max-height: 175px;"></a> <img width="441" height="1"> <br /> </p> </td> </tr> <tr> <td colspan="3"> <sub> <sup> Image from Gale Studio and Keera Hails demos are Copyright © 2011 - 2022 Keera Studios Ltd. All Rights Reserved. Keera, Keera Studios, Keera Hails, Gale, Gale Studio are trademarks of Keera Studios Ltd. </sup> </sub> </td> </tr> </table>

Hands-on example

The two key ideas in Keera Hails are Reactive Values and Reactive Rules.
Reactive values are data holders or action endpoints that will contain, provide
and/or consume data. Reactive Rules just connect these values so that changes
propagate across.

A very simple example of an RV is the following construction, in which a passive
IORef is turned into active Reactive Value.

haskell
do -- Empower IORef with callback installation mechanism. This comes from the -- keera-callbacks library. -- -- passiveCBRef :: CBRRef Integer passiveCBRef <- newCBRef 0 -- Turn IO Ref into active reactive value (RV). -- -- RVs are type classes. We use the type of Reactive Fields, which have a -- trivial RV implementation. let activeCBRefRV :: ReactiveFieldReadWrite IO Integer activeCBRefRV = ReactiveFieldReadWrite (writeCBRef passiveCBRef) (readCBRef passiveCBRef) (installCallbackCBRef passiveCBRef)

We now define an RV that encloses a trivial monadic action:

haskell
-- do continues -- Define a write-only RV that prints whatever you put in it. let printer :: Show a => ReactiveFieldWrite IO a printer = wrapMW print

You can connect them together in a monadic environment:

haskell
-- Connect them using a reactive rule. In a GUI application, this code would -- in the controller, and would define connections between the model and -- the view. -- -- For bi-directional connections, see (=:=). activeCBRefRV =:> printer

If you now loop and put data in the IORef, it will be passed along
the reactive connection and printed to the output:

haskell
forever $ do threadDelay 1000000 -- 1 second reactiveValueModify activeCBRefRV (+1)

Using the same, simple ideas, you can define a RVs for, and connect, the fields
of GUI widgets, for files, for network sockets, etc.

Project Structure

The toolkit is divided in three parts:

  • Reactive Values: they are typed mutable values with event dispatching and
    access properties. They can be modified by lifting functions and applying
    lenses to them. They can also be connected so that they stay in sync during
    program execution.

  • Reactive bindings: Widget properties/attributes can be seen as
    reactive values. So can network sockets, files, application models ('model'
    as in MVC) and external resources (polling). Uni-directional, Functional
    Reactive Programming signal functions can also be wrapped into a pair
    of RVs (see Yampa). The idea is that, at the highest application level
    (controller), each layer is wrapped in a reactive container and connected
    to others.

    Backends for iOS and Android (using each platform's native UI toolkits) are
    also available. Samples can be found
    here and
    here.
    Please contact Keera Studios if you wish to use them.

  • MVC Architecture

    MVC is easily applied using hails. There are two easy ways of wraping pure
    models into RVs, depending on the level of change detection we need to detect
    and optimise.

    A pair Model-View, often needed by the controller, can be wrapped in an
    environment. The following packages implement a Gtk View and a Gtk
    environment.

    The following package generate default project skeletons that do "the right
    thing" (currently for Gtk+ only). The application takes the approach of
    "convention over configuration": certain modules will be expected to have
    predetermined names. If this is much of a problem, open a bug report.

    • keera-hails: Program that generates a project skeleton.

    We have a separate README that shows how to
    build your first app using keera-hails.

  • Applications can be simplified further. The following packages implement
    Gtk-based choreographies (M-V synchronizations and controller rule templates)
    and address other common features needed in applications.

Tutorials, papers and publications

<table> <tr> <td> <p align="center"> Building a reactive calculator in Haskell! <br /><br /> <a href="https://keera.co.uk/2020/05/28/building-a-reactive-calculator-in-haskell-1-5/" target="_blank"> <img src="https://keera.co.uk/wp-content/uploads/2022/04/hello-hails-web-calculator-css-final-orig-midres-short.gif" height="auto" alt="Keera Hails web demo app capture" style="max-height:175px;"></a> <img width="441" height="1"> <br /> <sup>Copyright © 2020 - 2021 Keera Studios Ltd. All Rights Reserved.</sup> <br /> </p> </td> </tr> </table>

For bibtex references to these articles, see Publications in http://www.cs.nott.ac.uk/~ixp/.

Applications and demos

Credits

I would like to thank the following people for fruitful discussions and collaborations.

  • Henrik Nilsson
  • Hamish Mackenzie (for helping me create the first GHCJS backend for Hails,
    and for Gtk2hs).
  • Leuite Stegeman (for helping me create the first GHCJS backend for Hails).
  • Guerric Chupin (for continuing this work and writing Arpeggigon).
  • Arsen Kostenko
  • Emilio Gallego
  • Paolo Capriotti
  • Florent Ballestrieri
  • David McGillicuddy
  • Philip Holzenspies
  • Ian-Woo Kim
  • Atze van der Ploeg
  • Simon Peyton Jones
  • Michał Gajda
  • I thank the audiences of the following talks on Reactive programming and
    Hails, for patientily listening to me complain about the state of the world
    and commenting on my work.
    • Haskell Symposium (2015), Vancouver, colocated with ICFP.
    • London (2014), Haskell Meetup
    • Nottingham (2014), FPLAD.
    • TFP (2014)
    • FPLab, Nottingham (2013)
    • CAES Group, UTwente (2013)
    • Babel Research Group, UPM (2010)

(Note: these people do not necessarily support anything I have to say.)

<!-- ## About the name Keera Hails was born from several experiments back when I was an MSc student and researcher in 2008-2009. Back then, it was clear that it was going to be called Hails, and I often discussed it with my colleagues by referring to it as ``Haskell on Rails''. I checked that the name wasn't taken, and so Hails was born. I wrote the first commercial program with this library in 2010, and I've been using it ever since. Many programs have now been written in Hails (including Gale, whose name sounds similar, means something related, and was also not arbitrary). In 2012, I received a message clients using the library telling me that they couldn't compile their program anymore. Apparently someone had published a library called ``Hails'' on Hackage (my hails was on github, but not on hackage). I asked the authors of that library to change its name, but they refused, telling me that they were there first. It's sad that we have to have these disputes in such a small community. We both think that we are right, and there is no easy way to resolve this matter without one of us giving something up. To avoid collisions, I call this library Keera Hails in all papers. Because there is no risk of confusion, I use the name Hails in this documentation. -->

Contributors

Showing top 5 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from keera-studios/keera-hails via the GitHub API.Last fetched: 6/28/2026