threepenny-gui: GUI framework that uses the web browser as a display.

[ bsd3, gui, library, web ] [ Propose Tags ]

Threepenny-GUI is a GUI framework that uses the web browser as a display.

It's very easy to install because everyone has a web browser installed.

A program written with Threepenny is essentially a small web server that displays the user interface as a web page to any browser that connects to it. You can freely manipulate the HTML DOM and handle JavaScript events from your Haskell code.

Stability forecast: This is an experimental release! Send me your feedback! Significant API changes are likely in future versions.

NOTE: This library contains examples, but they are not built by default. To build and install the example, use the buildExamples flag like this

cabal install threepenny-gui -fbuildExamples

[Skip to Readme]


Manual Flags


Build example executables.


The library uses some techniques that are highly non-deterministic, for example garbage collection and concurrency. Bugs in these subsystems are harder to find. Activating this flag will expose more of them.


Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info


Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Versions [RSS],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, (info)
Change log
Dependencies aeson (>=0.7 && <0.10 || >=0.11 && <0.12 || >=1.0 && <2.3), async (>=2.0 && <2.3), base (>=4.8 && <4.21), bytestring (>=0.9.2 && <0.13), containers (>=0.4.2 && <0.8), data-default (>=0.5.0 && <0.8), deepseq (>=1.3.0 && <1.6), exceptions (>=0.6 && <0.11), file-embed (>=0.0.10 && <0.1), filepath (>=1.3.0 && <1.6.0), hashable (>=1.2.0 && <1.5), safe (>=0.3 && <0.4), snap-core (>=0.9.0 && <1.1), snap-server (>=0.9.0 && <1.2), stm (>=2.2 && <2.6), template-haskell (>=2.7.0 && <2.23), text (>=0.11 && <2.2), transformers (>=0.3.0 && <0.7), unordered-containers (>=0.2 && <0.3), vault (>=0.3 && <0.4), vector (>=0.10 && <0.14), websockets (>=0.8 && <0.12.5 || > && <0.14), websockets-snap (>=0.8 && <0.11) [details]
License BSD-3-Clause
Author Heinrich Apfelmus
Maintainer Heinrich Apfelmus <apfelmus at quantentunnel dot de>
Revised Revision 1 made by HeinrichApfelmus at 2024-05-27T12:54:11Z
Category Web, GUI
Home page
Bug tracker
Source repo head: git clone git://
Uploaded by HeinrichApfelmus at 2024-02-08T21:31:50Z
Distributions LTSHaskell:, NixOS:, Stackage:
Reverse Dependencies 8 direct, 3 indirect [details]
Executables threepenny-examples-svg, threepenny-examples-drummachine, threepenny-examples-dragndropexample, threepenny-examples-currencyconverter, threepenny-examples-crud, threepenny-examples-chat, threepenny-examples-canvas, threepenny-examples-buttons, threepenny-examples-bartab
Downloads 32157 total (186 in the last 30 days)
Rating 2.25 (votes: 2) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2024-02-08 [all 1 reports]

Readme for threepenny-gui-

[back to package description]

AppVeyor Build Status Hackage Stackage LTS Stackage Nightly


What's this?

Threepenny is a GUI framework written in Haskell that uses the web browser as a display. It's very easy to install. See the

Project homepage

for more information on what it does and can do for you as a library user.


The library comes with many examples, which can be found in the samples folder. Follow the link for more information on how to run them.

Desktop Apps

Threepenny is mainly intended for writing GUI applications that run on the local network, and it relies on a web browser being installed. You can drop the latter requirement and integrate it a bit more tightly with you desktop environment by using the Electron framework. There is no fully automated support for this yet, but the documentation includes a tutorial on how to use Electron with Threepenny.

Technical overview

JavaScript FFI

A program written with Threepenny is essentially a small web server that displays the user interface as a web page to any browser that connects to it.

The web server displays a HTML page, which in turn establishes WebSocket connection with the server. The server uses this connection to send JavaScript code that is executed in the client. In the library, this appears as a JavaScript Foreign Function Interface (FFI). The documentation includes more information on the design of the JavaScript FFI.


The frequent communication between browser and server means that Threepenny is best used as a GUI server running on localhost. You can use it on your local network as well.

If you want to reduce latency, the best option is to generate larger blocks of JavaScript code and run them on the client. Consider this approach similar to a shading language. You can import any JavaScript library and use it from the JavaScript FFI.

If you don't want to write JavaScript, then you could choose a Haskell-like language like PureScript, Fay. You can also directly compile Haskell to JavaScript with Haste or GHCJS.

Future ideas

HTML rendering mode

It might be nice in the case of search engines to merely generate a DOM and render it, so that search engines can read the pages.

UI libraries

qooxdoo — provides a feature-complete widget set. One could wrap this in a type-safe API from Threepenny and get a complete, stable UI framework for free. Most of the "immediate feedback" like dragging things here, switching tabs there, are taken care of by the framework. All that would be left would be to provide the domain configuration and business/presentation logic.

There are plenty more like this, but this is the first that springs to mind that is good.


Many thanks to everyone who contributed, provided feedback or simply wrote an application using Threepenny! In particular, many thanks to:

Heinrich Apfelmus, Daniel Austin, Jeremy Barisch-Rooney, Steve Bigham, Simon Jakobi, Ken Friis Larsen, Daniel Mlot, Tim C. Schröder and many others

Special thanks to Simon Jakobi for co-maintaining this project.

Special thanks to Chris Done for starting the precursor project Ji.