Getting started

haskell.nix can automatically translate your Cabal or Stack project and its dependencies into Nix code.

The first steps are to ensure you have Nix installed and the binary cache set up on your machine.

Then you have the choice to set-up your project using the experimental Flake feature or Niv, which are 2 ways to pin nixpkgs with Nix.

If you have an existing Haskell project that you want to build with haskell.nix, you might prefer to use hix. hix is a more easy and user-friendly way to use haskell.nix, using it reduce considerably the size of the Nix expression you will have to maintain in your project codebase.

Setting up the binary cache

IMPORTANT: you must do this or you will build several copies of GHC!

You can configure Nix to use our binary cache, which is pushed to by CI, so should contain the artifacts that you need.

You need to add the following sections to /etc/nix/nix.conf or, if you are a trusted user, ~/.config/nix/nix.conf (if you don't know what a "trusted user" is, you probably want to do the former). [...] denote any existing entries.

extra-trusted-public-keys = [...] hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= [...]
extra-substituters = [...] https://cache.iog.io [...]

If you're running NixOS, you need to add/update the following in your /etc/nixos/configuration.nix files instead.

# Binary Cache for haskell.nix
nix.settings.trusted-public-keys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.settings.substituters = [
  "https://cache.iog.io"
];

NixOS-21.11 and older use slightly different settings.

# Binary Cache for haskell.nix  
nix.binaryCachePublicKeys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.binaryCaches = [
  "https://cache.iog.io"
];   

This can be tricky to get setup properly. If you're still having trouble getting cache hits, consult the corresponding troubleshooting section.

Create a project using Flakes

This section assumes you choose to uses the experimental flakes features, and so that you have added experimental-features = [ "nix-command" "flakes" ]; in your Nix configuration. You can look at the Wiki for more instructions.

The following nix flake init command creates a template hello package containing a flake.nix and nix/hix.nix file. The project can be used with regular nix tools. This template is defined in the NixOS/templates repository.

nix flake init --template templates#haskell-nix --impure
# `--impure` is required by `builtins.currentSystem`
nix develop
cabal build

To view the contents of the flake run:

nix flake show

To build a component with nix:

nix build .#hello:exe:hello

To build and run a component:

nix run .#hello:exe:hello

Scaffolding

The following code could be capy-pasted and will work with stack.yaml and cabal.project based projects.

Edit your flake.nix as:```nix { description = "A very basic flake"; inputs.haskellNix.url = "github:input-output-hk/haskell.nix"; inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable"; inputs.flake-utils.url = "github:numtide/flake-utils"; outputs = { self, nixpkgs, flake-utils, haskellNix }: flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ] (system: let overlays = [ haskellNix.overlay (final: _prev: { # This overlay adds our project to pkgs helloProject = final.haskell-nix.project' { src = ./.; compiler-nix-name = "ghc96"; # This is used by nix develop . to open a shell for use with # cabal, hlint and haskell-language-server shell.tools = { cabal = {}; # hlint = {}; # haskell-language-server = {}; }; # Non-Haskell shell tools go here shell.buildInputs = with pkgs; [ nixpkgs-fmt ]; # This adds js-unknown-ghcjs-cabal to the shell. # shell.crossPlatforms = p: [p.ghcjs]; }; }) ]; pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; }; flake = pkgs.helloProject.flake { # This adds support for nix build .#js-unknown-ghcjs:hello:exe:hello # crossPlatforms = p: [p.ghcjs]; }; in flake // { # Built by nix build . packages.default = flake.packages."hello:exe:hello"; }); }


> **Note:** Git dependencies
> 
> If you have git dependencies in your project, you'll need to [calculate sha256 hashes for them](./source-repository-hashes.md).

## Working with a project

Top-level attributes are Haskell packages (incl. dependencies) part of your project.

This section will show side by side the commands using Flakes experimental `new-command` API and legacy Nix commands.

To build the library component of a package in the project run:
```shell
nix build .#your-package-name:lib:your-package-name

There are also other components such as exes, tests, benchmarks and all. To build an executable:

nix build .#your-package-name:exe:your-exe-name

Flakes provide a devShell attribute that allow you to spawn a developer shell, here with cabal, hlint and haskell-language-server:

nix develop .
cabal repl your-package-name:lib:your-package-name
cabal build your-package-name

To open a shell for use with stack see the following issue.

Getting started with Hix

Hix is a command line tool that provides an easy way to add haskell.nix support to existing haskell projects.

The hix init command adds a flake.nix and nix/hix.nix file. After that the project can be used with regular nix tools.

For instance to run cabal build on the hello package from hackage:

cabal unpack hello
cd hello-1.0.0.2
nix run "github:input-output-hk/haskell.nix#hix" -- init
nix develop
cabal build

To view the contents of the flake run:

nix flake show

To build a component with nix:

nix build .#hello:exe:hello

To build and run a component:

nix run .#hello:exe:hello

Installing Hix

To use the other Hix features first install Hix with:

nix-env -iA hix -f https://github.com/input-output-hk/haskell.nix/tarball/master

To update run to the latest version run:

hix update

Using hix develop, hix flake, hix build and hix run

These commands work the same as the nix versions without using the flake.nix. Instead a boiler plate haskell.nix flake.nix file is added to .hix-flake/flake.nix and used from there.

The is can be useful if the project already includes a flake.nix or if you do not intend to maintain one.

Then all of these should work without the need to run hix init:

hix develop
hix flake show
hix build .#hello:exe:hello
hix run .#hello:exe:hello

Using hix-shell and hix-build

These commands behave like nix-build and hix-shell would if a boiler plate default.nix and shell.nix we present.

hix-shell --run 'cabal build all'
hix-build -A hsPkgs.hello.components.exes.hello

Going forward

Read through project function reference to see how the API works.

There are a number of things to explore further in the tutorials section.