threepenny-gui
GUI framework that uses the web browser as a display.
http://wiki.haskell.org/Threepenny-gui
| LTS Haskell 24.16: | 0.9.4.2@rev:1 |
| Stackage Nightly 2025-10-24: | 0.9.4.2@rev:1 |
| Latest on Hackage: | 0.9.4.2@rev:1 |
threepenny-gui-0.9.4.2@sha256:2e725905042fff5abd07ff32090eb252fd0863e5d9405593fd886401315edc87,8866Module documentation for 0.9.4.2
- Foreign
- Graphics
- Graphics.UI
- Graphics.UI.Threepenny
- Graphics.UI.Threepenny.Attributes
- Graphics.UI.Threepenny.Canvas
- Graphics.UI.Threepenny.Core
- Graphics.UI.Threepenny.DragNDrop
- Graphics.UI.Threepenny.Elements
- Graphics.UI.Threepenny.Events
- Graphics.UI.Threepenny.JQuery
- Graphics.UI.Threepenny.SVG
- Graphics.UI.Threepenny.Timer
- Graphics.UI.Threepenny.Widgets
- Graphics.UI.Threepenny
- Graphics.UI
- Reactive
Threepenny-GUI
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
for more information on what it does and can do for you as a library user.
Examples
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.
Latency
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.
Contributors
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.
Changes
Changelog for the threepenny-gui package
0.9.4.2 – Maintenance and snapshot release
- Bump dependencies for compatibility with GHC-9.12.
0.9.4.1 – Maintenance and snapshot release
- Bump dependencies for compatibility with GHC-9.8.
0.9.4.0 – Maintenance and snapshot release
- Fix support for SSL: Export
ConfigSSLconstructor.
0.9.2.0 – Maintenance and snapshot release
-
Add support for SSL.
To start the server as an HTTPS server, use the
jsUseSSLfield with appropriate parameters. For security reasons, no information is read from the environment in this case. -
Bump dependencies for compatibility with GHC-9.4.
-
Bump dependencies for compatibility with GHC-9.2.
0.9.1.0 – Maintenance and snapshot release
- Add support for websockets over SSL.
- Bump dependencies for compatibility with GHC-9.0.
0.9.0.0 – Maintenance and snapshot release
-
The events
contextmenu,mousedown,mousemoveandmouseupnow returnDoublecoordinates instead ofInts. This change reflects updates to the underlying browser APIs and the jQuery library. #238Users who prefer to keep working with
Intcoordinates may use the addedroundCoordinatescompatibility function. -
Bump dependencies to allow
aeson1.5.
0.8.3.2 – Maintenance release
- Bump dependencies for compatibility with GHC-8.10.
0.8.3.1 – Maintenance release
- Bump dependencies for compatibility with GHC-8.8.
- Bump dependencies to allow
hashable1.3.0.0. - Remove support for GHC 7.6 and 7.8.
0.8.3.0 – Maintenance and snapshot release
- Export
keypressevent. - Fix the spelling of the
refXandrefYSVG attributes.refXandrefYare added toGraphics.UI.Threepenny.SVG.Attributes, the old lowercase versions are deprecated. - Invoke compatibility mode of IE11 for jQuery v3.2.1.
- Compatibility with GHC-8.6.1
0.8.2.4 – Maintenance release
- Remove redundant dependencies on
network-uriandnetwork - Bump dependencies to allow
aeson1.4.0.0 - Exclude
websockets0.12.5.0 from dependencies.
0.8.2.3 – Maintenance release
- Compatibility with GHC-8.4.1
- Bump dependencies to allow
aeson1.3.0.0 - Bump dependencies to allow
exceptions0.10.0 - Bump dependencies to allow
snap-server1.1.0.0
0.8.2.2 – Maintenance release
- Bump dependencies to allow
exceptions0.9.0
0.8.2.1 — Maintenance release
- Bump dependencies to allow
async2.2 - Fix a compatibility issue with Cabal-2.0
0.8.2.0 — Snapshot release
- Add
getCookiesfunction that retrieves the cookies sent with the HTTP request when the browser window connects (to the websocket). #137 - Allow Electron process to be accessed from JavaScript FFI. #200 This means that Threepenny is now more useful when used with the Electron framework, see doc/electron.md for more information on that.
- Bump dependencies to allow
file-embed0.0.10.1
0.8.1.0 — Snapshot release
- Improve documentation and handling of call buffering (
CallBufferMode). The default call buffer mode was documented incorrectly, it wasBufferRunand is nowFlushOften. #163, #191, #192 - Add new default
CallBufferMode:FlushOften. This mode is likeBufferRun, but will flush the buffer at everyonEventas well, leading to less confusion when using the library in most circumstances. #191 - Add new
CallBufferMode:FlushPeriodically. This mode is likeBufferRun, but will flush the call buffer every 300ms if nonempty. #192 - Add support for custom DOM events (
CustomEvent). #196 - Expose JavaScript FFI functions
toJSObjectandliftJSWindowinGraphics.UI.Threepenny. This is useful for linking the lifetime of JavaScript objects to the lifetime ofElement. #181 - Use
jsLogparameter to log exceptions. #185 - Update bundled jQuery to version 3.2.1. #186
0.8.0.1 — Maintenance release
- Bump dependencies for compatibility with GHC-8.2.1
- Bump dependencies to allow
websockets0.12
0.8.0.0 — Snapshot release
Graphics.UI.Threepenny
- Fix
getElementByIdto properly returnNothingwhen no element with the givenidattribute is present. #129. - Bring back
loadFileandloadDirectory. #110 - Add
MonadUItypeclass for easier lifting in custom monad stacks. #173
JavaScript FFI
- Implement batching / buffering for FFI calls. #131. Several calls to the
runFunctionfunction may now buffer the JavaScript code and send it to the browser window in a single message at a later time. This improves performance considerably. - Clarify semantics for exceptions. See the file
doc/javascript-ffi.mdfor more.- The
UImonad now supports exception handling by being an instance of the type classesMonadThrowandMonadCatch. - The function
callFunctioncan now throw aJavaScriptExceptionexception to the Haskell side. - The function
runFunctionnow terminates the connection to the browser window whenever the JavaScript code within throws an exception.
- The
- Exceptions in the
UImonad that are not handled are now printed properly for better debugging. #145 - Clarify semantics of the
disconnectevent. It is now triggered more reliably. #133. - Remove unnecessary client response when exporting event handlers. #131.
- Add option
jsWindowReloadOnDisconnectto reload the browser window #130 whenever the WebSocket connection is broken. This is useful for e.g. mobile devices, which tend to disconnect WebSocket connections very often.
Dependencies
- Add dependency on
exceptions
0.7.0.2 — Maintenance release
- Bump dependencies to allow
aeson1.2 - Bump dependencies to allow
websockets0.11
0.7.0.1 — Maintenance release
- Bump dependencies to allow
aeson1.1 - Bump dependencies to allow
vector0.12 - Bump dependencies to allow
websockets0.10
0.7.0.0 — Maintenance and snapshot release
- JavaScript FFI: Reduce communication from browser to server when creating
Elements. New functionunsafeCreateJSObjectto create JavaScript objects without waiting for a client response. #131 - JavaScript FFI: Implement escape sequence ‘%%’ when calling JavaScript functions. #132.
- Change type of
onEventfunction to allow unregistering events. - Add function
timestampfor simple performance measurements. - Update JavaScript dependencies to jQuery 2.2.3
- Adapt to GHC 8.0.1. #138
- Bump dependencies to allow
aeson1.0 - Bump dependencies to allow
data-default0.7 - Bump dependencies to allow
snap-core1.0 andsnap-server1.0 - Bump dependencies to allow
template-haskell2.11 - Bump dependencies to allow
websockets-snap0.10
0.6.0.6 — Maintenance release
- Bump dependencies to allow
base4.9 - Bump dependencies to allow
aeson0.11
0.6.0.5 — Maintenance release
- Bump dependencies to allow
async2.1 - Bump dependencies to allow
transformers0.5
0.6.0.4 — Maintenance release.
- Elements that have become unreachable, for instance because they have been removed from the DOM and are no longer reachable in the Haskell code, will be garbage collected again. Fix #109, #113.
- Adjust dependencies.
- Add
<meta>tag to indicate UTF8 encoding in html file. #116
0.6.0.3 — Maintenance release.
- Temporary fix for #109, which was causing event handlers to be discarded. Unfortunately, this means that elements are currently not garbage collected after they have been removed from the DOM tree.
0.6.0.2 — Maintenance release.
- Remove unused direct dependencies, in particular ** attoparsec-enumerator ** utf8-string ** MonadCatchIO-transformers ** time
0.6.0.1 — Maintenance release.
- The
ADDRenvironment variable is now parsed correctly. - Now builds on GHC 7.8 and GHC 7.10
- The example source code in the
samplesfolder has been reorganized and consolidated.
0.6.0.0 — Snapshot release.
- The internals of the JavaScript FFI has been reimplemented completely. A new module
Foreign.JavaScriptexports a bare JavaScript FFI in case you want to write a custom GUI framework. However, the moduleGraphics.UI.Threepennyis not compatible with it, even though it builds on top of it. - The fields of
Configtype for server configuration are now prefixed withjsinstead oftp. Example:jsPort,jsStatic. - The functions
loadFileandloadDirectoryhave been removed, as I felt that thejsStaticoption is sufficient for most use cases.
0.5.0.0 — Snapshot release.
- Possibility to specify IP address to bind the server to.
- FFI now supports callbacks into Haskell. Remove
callDeferredFunctionfunction. Graphics.UI.Threepenny.Canvas.SVGfor creating SVG elements and attributes.- 2D graphics API in
Graphics.UI.Threepenny.Canvasis beginning to grow. Boolis now correctly marshalled to JavaScript.Textcan now be marshalled to JavaScrtip.
0.4.2.0 — Maintenance release.
- Dependency
bytestring >=0.9.2is now implemented correctly. - Allow newer versions of
aesondependency. - Allow newer versions of
network,transformersandtemplate-haskelldependencies. - Helper scripts in the
samplesdirectory now assume that you use a cabal sandbox for development. - The
UImonad is now an instance of theApplicativeclass.
0.4.1.0 — Maintenance release.
- Dependency on
textpackage now from version 0.11 to 1.1.*. - Dependency on
aesonpackage replaces the former dependency on thejsonpackage. - Unicode characters are now transmitted correctly to the browser. #75, #62.
- Change default port number to 8023. #64
0.4.0.2 — Bugfix release.
- Fix CSS bug for
gridfunction.
0.4.0.1 — Maintenance release.
- Adjust package dependencies.
0.4.0.0 — Snapshot release.
- New
UImonad for easier JavaScript FFI and recursion in FRP. - Garbage collection for DOM elements. (Unfortunately, this doesn’t support using custom HTML files anymore, see issue #60.)
- First stab at widgets.
- Bump dependencies to allow
websockets0.8
0.3.0.0 — Snapshot release.
- Browser communication with WebSockets.
- First stab at FRP integration.
0.2.0.0 — Snapshot release.
- First stab at easy JavaScript FFI.
0.1.0.0
- Initial release.