Skip to content
Reproducible builds and development environment for Go
Branch: master
Clone or download
Pull request Compare This branch is 12 commits behind kamilchm:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Circle CI

go2nix - because Go and Nix are both amazing

For Nixers - packaging Go applications


go2nix provides an autmatic way to create Nix derivations for Go applications.

  1. Start with app sources than can be built on your machine with go build. It means that you need to get all dependencies into current GOPATH.
  2. Run go2nix save in application source dir where main package lives. This will create 2 files default.nix and deps.nix that can be moved into its own directory under nixpkgs.


If you are not sure how to organize your directory structure, read this official guide first.

Our project will be called influxdb-demo and this demo will be using the influxdb client library.

  1. But first, prepare the project directory:

     mkdir example
     cd example
     mkdir bin pkg src
  2. Change into a shell environment which contains GO and GIT:

     nix-shell -p go git go2nix

Note: Make sure go2nix is at least version 1.1.1

  1. Then set the GOPATH:

     export GOPATH=`pwd`
     mkdir -p src/
  2. Prepare src/

     package main
     import (
     const (
         MyDB = "square_holes"
         username = "bubba"
         password = "bumblebeetuna"
     func main() {
         // Make client
         c, err := client.NewHTTPClient(client.HTTPConfig{
             Addr: "http://localhost:8086",
             Username: username,
             Password: password,
         if err != nil {
             log.Fatalln("Error: ", err)
         // Create a new point batch
         bp, err := client.NewBatchPoints(client.BatchPointsConfig{
             Database:  MyDB,
             Precision: "s",
         if err != nil {
             log.Fatalln("Error: ", err)
         // Create a point and add to batch
         tags := map[string]string{"cpu": "cpu-total"}
         fields := map[string]interface{}{
             "idle":   10.1,
             "system": 53.3,
             "user":   46.6,
         pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
         if err != nil {
             log.Fatalln("Error: ", err)
         // Write the batch

Note: We use go influxdb client as an external library example.

  1. Create a GIT repository

     cd src/
     git init
     git add influxdb-client.go
     git commit -m 'initial commit'

    Also create the repository on, in this example it would be

     git remote add origin
     git push -u origin master

Note: go2nix requires a GIT repository to retrieve the commit hash and the remote so it can generate the values as name, version, rev and goPackagePath in the default.nix file.

  1. Download the dependency the go-way

     go get

Note: go get will populate src/ for you.

  1. Building the project

     go build
  2. Generate default.nix/deps.nix

If go was able to build the binary, use go2nix to derive the default.nix and deps.nix:

  go2nix save

Note: This gives you a default.nix and a deps.nix which can be put into nixpkgs but, if you want to use it with nix-shell, you need some tiny adaptions.

  1. The default.nix file we generated

     # This file was generated by go2nix.
     { stdenv, buildGoPackage, fetchgit, fetchhg, fetchbzr, fetchsvn }:
     buildGoPackage rec {
       name = "influxdb-demo-${version}";
       version = "20161030-${stdenv.lib.strings.substring 0 7 rev}";
       rev = "718c85cd733bca964abf03f5371c939d19845f72";
       goPackagePath = "";
       src = fetchgit {
         inherit rev;
         url = "";
         sha256 = "0csbqcnncklimysgcbxlj190bynx1ppvyxvl5viz40fvbcj4l8xb";
       goDeps = ./deps.nix;
       # TODO: add metadata
       meta = {

Note: Update the fetchgit url to use https instead of ssh or nix-build won't be able to fetch the software later.

Note: If you want to use this default.nix in nixpkgs you should extend the meta section and correct the goPackagePath.

  1. The deps.nix we generated

    # This file was generated by go2nix.
        goPackagePath = "";
        fetch = {
          type = "git";
          url = "";
          rev = "bcb48a8ff2e9c118d5cfa04f03a62134b9c414c7";
          sha256 = "1f4jp7p2xxlsxhqbvglcl95y7fhab0w6zsvyqmqglmi0g1c5v21z";
  2. Building the project using nix-build

    nix-build -E 'with import <nixpkgs> { };  callPackage ./default.nix {}'

This will print something like this:

    these derivations will be built:
    building path(s) ‘/nix/store/45jjx5jakvlgwzq358pivr5x8xpgdsck-influxdb-bcb48a8’
    building path(s) ‘/nix/store/pqlqq2wjgixvf5j6qmrv5qyjh1bc6i8q-influxdb-demo-718c85c’
    exporting (rev bcb48a8ff2e9c118d5cfa04f03a62134b9c414c7) into /nix/store/45jjx5jakvlgwzq358pivr5x8xpgdsck-influxdb-bcb48a8
    exporting (rev 718c85cd733bca964abf03f5371c939d19845f72) into /nix/store/pqlqq2wjgixvf5j6qmrv5qyjh1bc6i8q-influxdb-demo-718c85c
    Initialized empty Git repository in /nix/store/45jjx5jakvlgwzq358pivr5x8xpgdsck-influxdb-bcb48a8/.git/
    Initialized empty Git repository in /nix/store/pqlqq2wjgixvf5j6qmrv5qyjh1bc6i8q-influxdb-demo-718c85c/.git/
    remote: Counting objects: 3, done.        
    remote: Compressing objects: 100% (2/2), done.        
    remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0        
    * branch            HEAD       -> FETCH_HEAD
    Switched to a new branch 'fetchgit'
    removing `.git'...
    remote: Counting objects: 540, done.        
    remote: Compressing objects: 100% (506/506), done.        
    remote: Total 540 (delta 34), reused 179 (delta 6), pack-reused 0        
    Receiving objects: 100% (540/540), 1.44 MiB | 0 bytes/s, done.
    Resolving deltas: 100% (34/34), done.
    * branch            HEAD       -> FETCH_HEAD
    Switched to a new branch 'fetchgit'
    removing `.git'...
    building path(s) ‘/nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin’, ‘/nix/store/av17zlfgnppl704wwxnh5pjpkcxac9k3-go1.7-influxdb-demo-20161030-718c85c’
    unpacking sources
    unpacking source archive /nix/store/pqlqq2wjgixvf5j6qmrv5qyjh1bc6i8q-influxdb-demo-718c85c
    source root is influxdb-demo-718c85c
    patching sources
    grep: Invalid range end
    unpacking source archive /nix/store/45jjx5jakvlgwzq358pivr5x8xpgdsck-influxdb-bcb48a8
    /tmp/nix-build-go1.7-influxdb-demo-20161030-718c85c.drv-0/go /tmp/nix-build-go1.7-influxdb-demo-20161030-718c85c.drv-0
    post-installation fixup
    shrinking RPATHs of ELF executables and libraries in /nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin
    shrinking /nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin/bin/influxdb-demo
    stripping (with flags -S) in /nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin/bin 
    patching script interpreter paths in /nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin
    shrinking RPATHs of ELF executables and libraries in /nix/store/av17zlfgnppl704wwxnh5pjpkcxac9k3-go1.7-influxdb-demo-20161030-718c85c
    patching script interpreter paths in /nix/store/av17zlfgnppl704wwxnh5pjpkcxac9k3-go1.7-influxdb-demo-20161030-718c85c

Note: The resulting binary will be in /nix/store/9k4v7rhs5606fyia8mb341k71m3yrcbq-go1.7-influxdb-demo-20161030-718c85c-bin.

  1. Enabling nix-shell

    In order to use nix-shell you need to create a shell.nix file:

      pkgs = import <nixpkgs> {};
    in pkgs.callPackage ./default.nix {}

    That will pass the derivations for stdenv, buildGoPackage, fetchgit, fetchhg, fetchbzr, fetchsvn into your package derivation. It will use nixpkgs (your current channel).

    After you updated the default.nix you can now use nix-shell:

    these paths will be fetched (47.89 MiB download, 248.86 MiB unpacked):
    fetching path ‘/nix/store/i76bwv541a7zj576hkdia62169r2nl0z-bash-4.3-p48-doc’...
    fetching path ‘/nix/store/g4f1bms36hgg5abfd8xc4bj6sfzsy61d-bash-4.3-p48-info’...
    fetching path ‘/nix/store/aql31436x2fgr3rdj4fwbrgkvzw2kqf4-iana-etc-2.30’...
    fetching path ‘/nix/store/bb2njjq32bh1wl2nl1zss0i8w1w2jgrz-tzdata-2016f’...

    After the dependencies were built you can now use: go build to build your software as usual!

    Note: You can also arrange a default.nix so that it can be used by nixpkgs and nix-shell but this is not covered here.

Example Leaps

Some projects are built using go get and for these you need to identify the src directory to run go2nix save from. So here is another example:

  1. nix-shell -p go2nix git go
  2. cd mktemp -d
  3. export GOPATH=pwd
  4. go get
  5. cd src/
  6. go2nix save

Note: The resulting default.nix and deps.nix are created in the directory you are currently in.

For Gophers - reproducible development and build environments

stay tuned


The preferred way of installing go2nix is to use nix like nix-env -iA go2nix or using it declaratively.

But you can also use go get

You can’t perform that action at this time.