Stack at Front Row Education

by @gregwebs on June 26, 2015

Stack is a Haskell development tool for package management and project building. To build your Haskell project with stack, first install stack, and then just run stack build.

Stack is an alternative to using cabal-install. Unlike cabal-install, stack features:

Support for projects

My first commit at Front Row Education was to add a stack.yaml file. A commercial project always ends up with many .cabal files. I have written build scripts for such projects at least 4 times at 3 different companies. This is in addition to authoring build scripts for open-source projects, including a package called cabal-meta designed to make dealing with a multi-cabal file project easier.

Every build system I have created has been problematic. Usually it consists of bash scripts because that always seems like an easy way to get started.

I have found cabal sandbox add-source to be buggy for some of my use cases. But even if that was not the case, the project workflow never ends up being 1st class. You have to write a wrapper for the build that initializes a sandbox and adds the other project.

With stack, you list where the .cabal files are for your project and everything just works. Bad build systems end up being a net huge distraction, so I am relieved that FPComplete has put in the effort needed to help the Haskell community make a great project build tool.

I also contribute to several open source projects (wai, yesod, and persistent, among others) that contain multiple .cabal files. Stack makes development there much nicer also.

At Front Row Education we merged multiple haskell git repositories into a single git repository that is now built with stack for development, continuous integration, and deployment. We spent less than a man-week (this includes staying involved with the stack project by reporting bugs and features and writing this post). At a previous company I worked at, more than a man-month was spent producing a worse build system. With stack, there was no build system to create, we just had to switch over from cabal. The only real build task was to make sure caching worked in Circle CI, our continuous integration provider. CircleCI made this easy: here are the main things we needed to add:

    - "~/.stack"
    - stack test --only-snapshot:
        timeout: 1800

Support for package curation

Stacakge is a curated set of packages known to build well together. stack has first class support for building against stackage and helping you figure out when your need dependencies out of your current package set.

Package management that works

cabal sandboxes together with freezing made it possible to have a consistent build of a Haskell project that would not break another project. But there were still major problems.

Note that stack does not garbage collect unused packages for you. However, 95% of the packages you use will probably come from stackage so you will end up with a high degree of package re-use across projects. You can always delete stackage snapshots (as you move on to newer ones) with the knowledge that it will never change a build plan of an existing stack project.

Simple workflows

In addition to better package management, With stack you don’t have to do

Stack is not perfect for everyone

Don’t use stack

Application authors that produce binaries should always build with exact (frozen) dependencies, and they will benefit a lot from stack. Libraries rarely freeze any of their dependencies and instead seek to support wide version ranges. Many library authors find it convenient to test against the latest stackage build: stack makes this workflow simple. However, others wants to continually test against the latest packages from hackage. Since cabal defaults to this behavior, cabal may always be better at this use case even as stack’s support for this use case improves.

Additionally, stack is young software.

The good news is that you can build a project with both cabal and stack and the two tools will not conflict.

Stack works well at Front Row Education

We worked around the lack of support in yesod devel (a yesod project re-compiler) by writing an inotify script that isn’t quite as good. Stack support should be landing in yesod devel in the future and there are already efforts to add stack support to many other tools.

Other than the above, everyone at Front Row was able to switch to using stack without difficulty and we are enjoying the ability to run stack build or stack test and have it work across all our project’s packages.