While web technologies and apps “in the cloud” are easily the dominant trend in application programming these days, there are still some situations in which reliable old desktop apps are superior. For example, most of my experience is in the defense industry, and there is no way the cloud would get trusted with sensitive files without appropriate protections. So how can we leverage the efforts and progress of web interface programming on the desktop, especially with regard to Haskell?
One option that I have some experience with is threepenny-gui, which uses the web browser as an interface to a Haskell backend server that runs locally (or over a LAN – really any low latency situation). An early version of threepenny is used in FNIStash. While effective, something just feels wrong to me about running desktop applications inside a browser application. Really what I’d like to do is incorporate browser functionality inside my applications instead of relying on Google, Mozilla, or even Microsoft.
Enter the Chromium Embedded Framework. It’s a fully functioning, bare-bones browser and javascript engine packed inside a .dll or .so file. Add some tabs, a URL bar, bookmarks, etc, and you have a modern browser. Alternatively, you can use CEF to provide HTML and JS driven GUIs for desktop applications. Indeed, the Steam client does this very thing! Adobe uses it as well. In fact, it’s pretty popular.
CEF provides a C API, which we can call from Haskell with appropriate bindings. I cut my teeth recently with the bindings-dsl by defining the bindings to the low level interface of the HDF5 library. Bindings to the CEF library seemed like a good follow on activity, especially since I’d like to use it in my own Haskell projects.
So I created bindings-cef3, Haskell bindings for the CEF3 C API. The package includes an optional example program that creates a browser window and loads a URL. There’s a snapshot below. These bindings are very low level, so there is ample opportunity to wrap them in a smarter, more convenient Haskell API. This is something I plan to do myself eventually, unless a more experienced Haskeller beats me to it!
Beware that because of the multiple interdependent types in CEF3, nearly all of the bindings are provided in a single file. It can take a while to preprocess and compile. When I was working on it, I had up up the RAM on my virtual machine from 4 GB to around 5 GB to avoid cryptic gcc errors. If anyone knows a better way to structure the library to avoid these hurdles, I’d love to hear it.
The library is not currently on Hackage as of this writing, and that is intentional. The current version only supports Linux, and being an occasional Windows Haskell developer myself, I don’t like the idea of keeping out Windows (and MacOS) users. Only a little more coding effort and a decent amount of testing effort is required for other platforms, and I welcome contributions from anyone wanting to help. Once it has been vetted a little more and better compatibility is implemented, joining Hackage with other bindings library seems only natural.
While bindings to CEF3 is just a first step toward having “true” Haskell desktop GUIs driven by web technologies, it’s an important step. More experimentation is needed to uncover quirks and limitations; I’m certainly no CEF expert. In fact, I probably know only as much as is necessary to get the example application working 🙂 . Hopefully this library will help out anyone frustrated with Haskell GUIs like I have been before!
It would be neat if there was something similar for atom-shell… I’d imagine someone attempting such a project could reuse some of your work. Have you looked into that at all?
https://github.com/atom/atom-shell/
I’ve actually just started looking into atom-shell. It’s javascript powered, so while Haskell might not work, Purescript would be a fun alternative.
In my opinion Thrust is a better alternative for Haskell apps. Projects like node-webkit, atom-shell are built with node.js development in mind, in comparison language bindings for Thrust use standard IO to communicate with the process and looks like it would be easier to deploy.
Here is the Hacker News discussion: https://news.ycombinator.com/item?id=8604716
Interesting. I hadn’t heard of Thrust. I’m more focused on the GUI aspect of any such app prsently, so my focus is on learning how to wrangle the javascript problem. Purescript has been really nice in that regard, and is applicable to any HTML5 deployment system. If I ever get to a situation in which I need access to the heavy metal for performance, I’ll give Thrust a look. Thanks for the tip!
Hey, thanks a lot for this effort!
I fully understand the need to have a web gui outside the browser. All the tools I’m currently building fall into that category, because they are for internal use in a graphics studio, with sensitive material. We are usually forced to use QT or something like it, but I really prefer using HTML5/CSS, except that it usually means using the installed browser, which we have no control (it usually ends being IE).
So, did you have any luck in porting your bindings to Window? That would be a dream. There are nice Haskell FRP frameworks that could squash javascript like an insect if they could share its portability.
Take a look at this nice project being done by Ryan Trinkle, Reflex FRP:
Video 1/
Video 2
Hi! Thanks for the kind comments. I never did do a Windows port, and in fact never used the library in a project at all outside of the demo app. My programming interests changed so I no longer had as much motivation to get it done. It started to seem more and more silly to me to have a big Haskell container for a web browser and then code most of the app in javascript. With solutions like Atom combined with a Haskell-like language that compiles to Javascript (like Purescript, which I like a lot), you can avoid Haskell land entirely if you want.
The problem I see with Atom (now Electron?) or node-webkit is, well, node. It is really weak for security, Haskell’s STM is quite important in this regard. But one could obviously use node just for the webkit shell and serve Javascript from a Haskell backend, or rather, serve Purescript.
Thanks for the tip.
Just a final note. There are now Haskell bindings for Qt Quick, which has a Webkit view. I’m going to try doing a simple browser in it, I believe it is trivial. Regardless if you use it for web, the Qt’s QML language seems very competent for making GUIs, and is similar to CSS.
HsQML Hackage
HsQML Video