Automate Haskell development with nixpkgs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Peter J. Jones 08074a73c1
Ensure hoogle is in the interactive environment
преди 3 месеца
nix New (Experimental) Feature: Build fully static executables via musl преди 4 месеца
test New (Experimental) Feature: Build fully static executables via musl преди 4 месеца
.gitignore Switch to Cabal v2 style aliases преди 1 година
LICENSE Rework everything so the `nix-hs' shell script isn't necessary преди 8 месеца Update the commit hash in to a newer version преди 7 месеца
default.nix Ensure hoogle is in the interactive environment преди 3 месеца

Haskell + nixpkgs = nix-hs

Are you a Haskell programmer? Do you use nixpkgs? Want to make using those two together really simple? You're in luck.

This project provides a Nix file that makes working with Haskell projects very simple. What does it do for you? Well, here are just a few of the things you'll love:

  • cabal2nix is automatically called when your Cabal file changes
  • Your package can be built with nix-build
  • Interactive development environment via nix-shell
  • Easily use any version of GHC in nixpkgs
  • Works with direnv

Geting Started

Create a default.nix file that looks something like this:

{ pkgs ? import <nixpkgs> {}

  nix-hs-src = fetchGit {
    url = "";
    rev = "445a8246236fd380eb3310853f271ee4aed7f3f4";

  nix-hs = import "${nix-hs-src}/default.nix" { inherit pkgs; };

in nix-hs {
  cabal = ./mypackage.cabal;

And a shell.nix that looks like this:

# Load an interactive environment:
(import ./. {}).interactive

That's it! Now nix-build and nix-shell just work!


In addition to the cabal argument to the nix-hs function, there are other ways to control how your package is built.

Enable Flags from the Cabal File

If you have a flag defined in your package's cabal file you can enable it using the flags argument:

nix-hs {
  cabal = ./mypackage.cabal;
  flags = [ "someflagname" ];

Using a Broken Package

If one of your package's dependencies can't be built you can try overriding it:

nix-hs {
  cabal = ./mypackage.cabal;

  overrides = lib: self: super: with lib; {
    pipes-text = unBreak (dontCheck (doJailbreak super.pipes-text));

Integrating Your Text Editor and Shell

The best way to let your text editor and shell use the environment created from Nix is to use direnv. Here's an example .envrc file:

# -*- sh -*-

# Load an environment from Nix:
use nix

# Reload if these files change:
watch_file mypackage.cabal

NOTE: Make sure you have a shell.nix file that exposes the interactive attribute of the derivation, like the example above.

Access to Static Binaries

The derivation generated by the nix-hs function makes it easy to access a “binary only” derivation. This is perfect for deployments or Docker containers where you don't want to bring along all of your package's dependencies (including GHC).

The bin attribute of the derivation gives you access to this binary only derivation. For example, to create a docker container:

{ pkgs ? import <nixpkgs> { }

  zxcvbn-ws = (import ./. { inherit pkgs; }).bin;

in pkgs.dockerTools.buildImage {
  name = "zxcvbn-ws";
  tag  = "latest";

  config = {
    Cmd = [ "${zxcvbn-ws}/bin/zxcvbn-ws" ];