Haskell CI Group meeting notes

Hi everyone,

Last week I hosted the first Haskell CI Group meeting. Notes from the meeting and other details are now available at the Haskell CI Group repository.

I’m looking forward to the next one next month! Let me know if you want to participate.


I didn’t realize so many people used nix in haskell land :sweat_smile:
I often get the impression from open source library and their respective CI that many folks use cabal directly (somehow), or stack.

I suppose the benefits nix provides vastly outweigh the various developer experience pain points it has.

1 Like

Yeah almost every Haskell discussion I get into these days turns into a Nix discussion :see_no_evil:


That is arguably not very good. But might be biased a bit due to your focus.


For what it’s worth, it seems like about 1/4 of the Haskellers I talk to regularly are using Nix. I suspect that we both have selection biases, and that the actual number is lower still, but that’s just a gut feeling.


I suspect the distribution is different for companies/organizations using Haskell, and individuals using Haskell, with the former using Nix to a greater extent.

1 Like

I’m unsure if this is the right thread to discuss this, but given its relevance to CI and Nix, I thought it might be pertinent. Our team relies heavily on Nix to bootstrap tooling across our projects. Frankly, we can’t envision handling our development environment without it. Presently, we maintain about seven Haskell services and many other services in various languages. This year, we chose to employ Nix for building some of the haskell projects and our internal packages, influenced by the perception that it’s the standard approach for industrial Haskell.

However, our experience hasn’t been positive. We’re using GHC 9.4, while nixpkgs remains at 9.2. As a small team, the challenges are manifold: building the package set, setting up caching (so that bootstrapping projects on macOS isn’t a lengthy ordeal), and the ongoing package set maintenance. I can’t help but feel that the “Nix overhead” is steep, and this might be hindering the Haskell community from adopting newer GHC versions. It would be beneficial for the CI group to address this concern.

I know about both very positive and more mixed experiences with Nix when using Haskell in industry. Similarly, many successful teams use a combination of Docker and cabal-install or Stack to great effect. Many industrial Haskell teams do use Nix, but many do not - I don’t think it can be called the standard right now.

I’ve heard good things about haskell.nix - have you tried that?

I second this. My experience with nix is : it’s great until you forgot how it works. This happens to me every 2 to 3 years when I have to reread the nix-pills (I might have read it 3 to 4 times now).
I guess it works better it a big team which can afford to have a nix expert.

I know nixpkgs has multiple Haskell package sets per compiler version, but I don’t remember the caching situation. Does it only cache the “main” (i.e. the one you get without specifying) one? Or does it not matter because the pinned package set inevitably doesn’t work across GHC versions for certain packages?

+1 to haskell.nix though. I use it for my personal projects because it doesn’t force a single package version for the entire world. I guess it doesn’t provide as much Haskell package caching either.

But tbh if you’re using Nix (any language) in a small operation, I would just force everyone to use Linux and then you get a quick and dirty cache for free from a CI server running NixOS. I’ve done that in the past (gitlab-runner on NixOS on Digital Ocean). macOS is a real cost to pay. I abandoned it as my main dev machine years ago.

To provide more clarity about our journey, let’s begin with a few assumptions:

  1. Any industrial Haskell project will have private packages not found in hackage.
  2. Such a project might also utilize forked packages with patches, which, for various reasons, haven’t been upstreamed.
  3. The project wouldn’t prefer using an outdated GHC version.
  4. The development team use macOS (arm64).

Given these conditions, building Haskell projects with Nix became a time-intensive task for us.

Our initial inclination was towards haskell.nix. However, our preliminary attempt using it was halted due to our reliance on private GitHub packages, which haskell.nix didn’t support back then. We also encountered challenges integrating flakes with Haskell.nix. When we revisited the idea of utilizing Nix for our Haskell projects this year, we did get haskell.nix to work. Yet, we opted against full adoption. The complexity of the solution meant that delving into the code and troubleshooting issues wasn’t straightforward. We didn’t aspire to become haskell.nix specialists, but it seemed almost mandatory for serious utilization. The last thing we wanted was to get stuck updating a package and then grapple with haskell.nix for days.

Our subsequent effort involved directly using the haskellPackages tooling in Nix. While this approach was somewhat successful, it lacked scalability, especially when juggling multiple projects and our numerous private packages.

Ultimately, we settled on crafting our package set, leveraging both haskell-flake and flake-parts. This allowed all our Haskell projects and packages to access the package set. We also incorporated caching through cachix and established a CI runner in cirus labs for aarch64-darwin. This ensured local builds were manageable. While our current setup operates efficiently, my initial message aimed to underscore the challenges of the setup process and the ongoing cost of maintaining it.


Thank you - this is very useful information! I’m sorry if I came across as saying “RTFM” - I certainly wasn’t trying to. You clearly know much more about Nix that I do.

If you’re interested in networking with others who face similar challenges, please get ahold of @chreekat, who runs the HF’s Haskell CI Group (the first message in this thread links to details). It may be useful for you to have a go-to group of people to share concerns and techniques with.


No worries. I just wanted to provide important context and hopefully a helpful experience report.

I’m currently swamped with my next challenge (figuring out how to build an async queue with STM and fused-effect and improving our event sourcing haskell packages), but I’ll reach out when I have more bandwidth.