diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000000000000000000000000000000000000..123140624f145d5d3884574cca99d1d4c45a9163
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,144 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1685518550,
+        "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "flake-utils_2": {
+      "inputs": {
+        "systems": "systems_2"
+      },
+      "locked": {
+        "lastModified": 1681202837,
+        "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "intervalset": {
+      "inputs": {
+        "flake-utils": [
+          "flake-utils"
+        ],
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "nur-kapack": [
+          "nur-kapack"
+        ]
+      },
+      "locked": {
+        "lastModified": 1685006270,
+        "narHash": "sha256-cJlbAF8m2PCX2iqepq3uKmKkOOF2bAjSpKMP4KXoevk=",
+        "ref": "refs/heads/master",
+        "rev": "2b449c3b8d88e7ed2008fe618846d437a4fd8ee5",
+        "revCount": 83,
+        "type": "git",
+        "url": "https://framagit.org/batsim/intervalset"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://framagit.org/batsim/intervalset"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1669833724,
+        "narHash": "sha256-/HEZNyGbnQecrgJnfE8d0WC5c1xuPSD2LUpB6YXlg4c=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "4d2b37a84fad1091b9de401eb450aae66f1a741e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "22.11",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nur-kapack": {
+      "inputs": {
+        "flake-utils": "flake-utils_2",
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1682575206,
+        "narHash": "sha256-hjoGc2gOa8IEcwDucNRoE2fryoRciPOJ7GBUShj3OY4=",
+        "owner": "oar-team",
+        "repo": "nur-kapack",
+        "rev": "7fa57b4170962b5c88d077d6f625628e7763c81c",
+        "type": "github"
+      },
+      "original": {
+        "owner": "oar-team",
+        "ref": "master",
+        "repo": "nur-kapack",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "intervalset": "intervalset",
+        "nixpkgs": "nixpkgs",
+        "nur-kapack": "nur-kapack"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "systems_2": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
index e7261e406124aeda9a6cdd65e0f263c41ff55baf..0db2a79ce288ae7602690178dc81630e46fbde58 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,3 +1,60 @@
 {
-  outputs = {...}: { };
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs?ref=22.11";
+    nur-kapack = {
+      url = "github:oar-team/nur-kapack/master";
+      inputs.nixpkgs.follows = "nixpkgs"; # tell kapack to use the nixpkgs that is defined above
+    };
+    flake-utils.url = "github:numtide/flake-utils";
+    intervalset = {
+      url = "git+https://framagit.org/batsim/intervalset";
+      inputs.nixpkgs.follows = "nixpkgs";
+      inputs.nur-kapack.follows = "nur-kapack";
+      inputs.flake-utils.follows = "flake-utils";
+    };
+  };
+
+  outputs = { self, nixpkgs, nur-kapack, flake-utils, intervalset }:
+    flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
+      let
+        pkgs = import nixpkgs { inherit system; };
+        kapack = nur-kapack.packages.${system};
+        release-options = {
+          debug = false;
+          doCoverage = false;
+          intervalset = intervalset.packages-release.${system}.intervalset;
+        };
+        debug-options = {
+          debug = true;
+          doCoverage = false;
+          intervalset = intervalset.packages-debug.${system}.intervalset;
+        };
+        debug-cov-options = debug-options // {
+          doCoverage = true;
+        };
+        base-defs = {
+          cppMesonDevBase = nur-kapack.lib.${system}.cppMesonDevBase;
+          loguru = kapack.loguru;
+          redox = kapack.redox;
+        };
+        callPackage = mergedPkgs: deriv-func: attrset: options: pkgs.lib.callPackageWith(mergedPkgs // options) deriv-func attrset;
+      in rec {
+        functions = rec {
+          batsched = import ./nix/batsched.nix;
+          generate-packages = mergedPkgs: options: {
+            batsched = callPackage mergedPkgs batsched {} options;
+          };
+        };
+        packages-debug = functions.generate-packages (pkgs // base-defs // packages-debug) debug-options;
+        packages-debug-cov = functions.generate-packages (pkgs // base-defs // packages-debug-cov) debug-cov-options;
+        packages-release = functions.generate-packages (pkgs // base-defs // packages-release) release-options;
+        packages = packages-release // {
+          ci-batsched-werror-gcc = callPackage pkgs functions.batsched ({ stdenv = pkgs.gccStdenv; werror = true; } // base-defs) release-options;
+          ci-batsched-werror-clang = callPackage pkgs functions.batsched ({ stdenv = pkgs.clangStdenv; werror = true; } // base-defs) release-options;
+        };
+        devShells = {};
+      }
+    );
 }
+
+
diff --git a/nix/batsched.nix b/nix/batsched.nix
new file mode 100644
index 0000000000000000000000000000000000000000..abf35fedabc2eef522206bef05114e6d99cd9d7a
--- /dev/null
+++ b/nix/batsched.nix
@@ -0,0 +1,50 @@
+{ stdenv, lib
+, cppMesonDevBase
+, meson, ninja, pkgconfig
+, intervalset
+, boost, cppzmq, gmp, loguru, rapidjson, redox, zeromq
+, doInternalTests ? true
+, debug ? false
+, werror ? false
+, doCoverage ? false
+}:
+
+(cppMesonDevBase {
+  inherit stdenv lib meson ninja pkgconfig debug werror doCoverage;
+  coverageGcnoGlob = "batsched.p/*.gcno";
+}).overrideAttrs(attrs: rec {
+  name = "batsched";
+
+  BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
+  BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
+
+  src = lib.sourceByRegex ../. [
+    "^meson\.build"
+    "^src"
+    "^src/.*\.?pp"
+    "^src/algo"
+    "^src/algo/.*\.?pp"
+    "^src/external"
+    "^src/external/.*\.?pp"
+  ];
+
+  buildInputs = [
+    intervalset
+
+    boost
+    cppzmq
+    gmp
+    loguru
+    rapidjson
+    redox
+    zeromq
+  ];
+
+  passthru = rec {
+    hasDebugSymbols = debug;
+    hasCoverage = doCoverage;
+    GCOV_PREFIX_STRIP = "5";
+    DEBUG_SRC_DIRS = [ "${src}/src" ] ++ intervalset.DEBUG_SRC_DIRS;
+    GDB_DIR_ARGS = map (x: "--directory=" + x) DEBUG_SRC_DIRS;
+  };
+})