How to get GHC 9.4.2 on NixOS?

GHC 9.4.2 has been out for more than a month but I still cannot get a hold of it on NIxOS. It is obviously not in the stable channel, but if I try the nixos-unstable channel I actually get GHC 8.10.7 instead of 9.4.2.

Here’s the command that I’m using:

$ sudo nix-channel --list
$ sudo nix-channel nixos-unstable --update
unpacking channels...

$ nix-shell -E "(import <nixos-unstable>{}).haskell.compiler.ghc942"
copying path '/nix/store/6g58925s3c4adzwxdk6q94c5lwg3hdcf-ghc-binary-8.10.7' from ''...
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7

I’ve also tried using the latest master tarball but that gives the same wrong result:

$ nix-shell -E "(import (builtins.fetchTarball { url = \"\"; }) {}).haskell.compiler.ghc942"
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7

Is there an easy way to use GHC 9.4.2 on NixOS?

ghc942 is still not readily available in Nixpkgs, at least to my knowledge. I guess the command fails and you end up having the default which is 902 for the unstable, and probably 8107 for the stable channel (I guessed this last part)?

I do not know a general way to find out which GHC versions are supported, and documentation is lacking behind, but there is just so much manpower. I think the documentation about Haskell in Nixpkgs should be improved. I think @sternenseemann has put a lot of work in this, but the documents are hidden in a PR, and have not been properly published nor released yet.

I always end up trying and looking through the issues on GitHub. For example, see haskell.packages.ghc942: make it work by lf- · Pull Request #191618 · NixOS/nixpkgs · GitHub.

EDIT: I think part of what I wrote is untrue. GHC 9.4.2 is available as a single package and

nix shell nixpkgs#haskell.compiler.ghc942

worked for me when the flake points to current nixpkgs-unstable. However, development with GHC942 is difficult because the package set haskell.packages.ghc942 does not work properly. I do not know why you end up with GHC 8.10.7.

1 Like

Using nix-shell this way gives you a dev-environment for compiling ghc 9.4.2. We apparently use the ghc 8.10.7 binary distribution for bootstraping, so that’s what is in the environment. Try something like

nix-build -E "(import <nixos-unstable>{}).haskell.compiler.ghc942"

and then run result/bin/ghc --version.

Besides that, dschrempf is sadly right, that currently only a small core set of hackage packages is already built by nix for ghc 9.4.2. otoh if you just want to develop with cabal-install and have it compile your dependencies, you might be fine.


I can confirm both of the above points. If you invoke the following file with nix-shell:

let pkgs = import <nixpkgs-unstable> { };

pkgs.mkShell {
  packages = with pkgs; [ haskell.packages.ghc942.ghc cabal-install zlib xz ];

you’ll get a perfectly serviceable ghc and cabal for ghc942, albeit without any pre built dependencies.

You can even get pre built dependencies and a haskell language server with my pr and much hacking; see for an example.

The PR still needs review but hopefully 9999years and I can get it merged soon.


Thanks for the helpful responses. I’m now at least able to install and use GHC 9.2.4.

Yeah, that is really what I want to do. I’ve never liked combining the system package manager with my development environment because the system package manager always lags behind and has a very limited selection of packages.

Ideally I would have one main ghc version (probably 9.2.4 currently) on my path and a bunch of alternative GHC versions, like ghc-8.10.7, ghc-9.2.4, and ghc-9.4.2 also on my path. Then cabal can automatically choose the one that is appropriate for each of the packages that I’m developing using the with-compiler option.

1 Like

You might like haskell.nix in that case: it’s Nix as a caching layer for haskell dependencies but the source of truth is cabal project files (at the cost of compiling more stuff since less will be cached).

For what it’s worth, on the standard Nix haskell infrastructure, if you use shell.nix/flake files, it’s quite possible to fix any issues you might have with the package set using an overlay. This is the thing that makes Nix more than just distribution-provided haskell, and it is thus possible to build large software systems on top of it.

See GitHub - lf-/flake-templates: Flake templates using flake-utils, subdirectory haskell, for one way to do overlays to change the package set as desired. You can also override things with callHackage/callHackageDirect (the latter if all-cabal-hashes is too old; although if you have that problem you can also just update all-cabal-hashes in an overlay).

1 Like

To be clear, you can just use nix-shell -p haskell.compiler.ghc942. Using -E means you want the dev env for building the derivation you get from the nix expression in the argument, not that you want the derivation itself. pkgs.mkShell can be used to create a faux derivation whose environment includes the things you want. But -p just says “give me these things in a shell please”

1 Like

But how do I use my nixos-unstable channel with nix-shell -p?

i’m in the jungle right now, but this may help you

Hmm, I didn’t find an answer directly in that thread, but it does link to the FAQ which has two ways to do it:

NIX_PATH=nixpkgs= nix-shell -p $software


nix-shell -I nixpkgs=channel:nixpkgs-unstable -p somepackage

I think the latter is much nicer. So in my case, I can use:

nix-shell -I nixpkgs=channel:nixos-unstable -p haskell.compiler.ghc942