Hakyll basic usage

Tags: hakyll, cabal, pandoc

Hakyll1 is a static site generator which turns a collection of text files written in markdown into a website. Static websites are fast, secure and easy to deploy. They are also simple and robust. If you host your website on your own server the ease of deploying a bunch of static files rather than maintaining a bespoke web application may be welcome. This site is hosted on OpenBSD which has a dedicated focus on security and simplicity. By using static webpages there is a minimal attack surface. Hakyll is built in Haskell2.

Once Hakyll has been installed and your website set up the basic workflow for using Hakyll is to write posts in Pandoc markdown3. You can then proceed to building the site. Depending on your tooling there are a variety of options for doing this. Using Cabal the site can be built using cabal new-run site build. If you changed the site.hs file then it is necessary to issue a rebuild cabal new-run site rebuild. The result in either case is a static website in the _site directory which can be copied/deployed to a web server, or accessed locally from a web browser using for example chrome _site/index.html. Using OpenBSD I find that Firefox and Chromium is unable to access any directories other than ~/Downloads (presumably for reasons of security). On this basis I find it handy that Hakyll includes a built in web server, albeit that it has limited functionality. The idea seems to be to issue a cabal new-run site watch in a terminal and navigate your browser to http://127.0.0.1:8000/4.

My preferred method of use is to browse & edit locally using Emacs, and then distribute using Hakyll. The simplest way to use Hakyll is that you cd into your repository and runhaskell hakyll.hs build (with hakyll.hs having whatever options you like). Hakyll will build a static HTML/CSS hierarchy inside _site/; you can then do something like firefox _static/index. (Because HTML extensions are not specified in the interest of cool URIs, you cannot use the Hakyll watch webserver as of January 2014.)

Consistent with the comments above running Hakyll using cabal new-run site watch and browsing locally in Firefox doesn’t work for me. Chromium is fine though. The advantage of the built in watch web server is that it tracks changes to your posts hence a quick refresh in the browser provides a preview. Note: cabal and runhaskell serve different purposes. runhaskell is used for executing Haskell programs without needing to compile them.

It is possible to specify in site.hs a deployment configuration to quickly facilitate uploading your site to your webserver. If your main function in site.hs is main = hakyll $ do change it to main = hakyllWith config $ do and add the following configuration directive to site.hs which modifies the default Hakyll configuration with instructions to deploy the built site:

config :: Configuration config = defaultConfiguration { deployCommand = "COMMAND" } 

where COMMAND is the relevant rsync or scp command to copy the files to the webserver. Deploy your site after a build with cabal new-run site deploy.


  1. https://jaspervdj.be/hakyll/↩︎

  2. https://www.haskell.org/↩︎

  3. https://pandoc.org/MANUAL.html#pandocs-markdown↩︎

  4. Gwern Branwen provides some useful insight over at https://www.gwern.net/About↩︎