diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml
new file mode 100644
index 0000000000000000000000000000000000000000..94883509ceeba1aa882e7b46fcdb0242afc84ead
--- /dev/null
+++ b/.github/workflows/nix.yml
@@ -0,0 +1,20 @@
+name: "Nix CI"
+
+on: [pull_request, push]
+
+jobs:
+  tests:
+    name: "Nix build on ${{ matrix.os }}"
+    runs-on: "${{ matrix.os }}-latest"
+    strategy:
+      matrix:
+        os: [ubuntu]
+    steps:
+      - uses: actions/checkout@v4
+      - uses: DeterminateSystems/nix-installer-action@main
+      - uses: DeterminateSystems/magic-nix-cache-action@main
+      - run: nix --accept-flake-config build -L
+      - run: nix --accept-flake-config run .#cachix push gepetto $(readlink result)
+        if: github.repository_owner == 'humanoid-path-planner'
+        env:
+          CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
diff --git a/COPYING b/LICENSE
similarity index 100%
rename from COPYING
rename to LICENSE
diff --git a/cmake b/cmake
index 657b07cb721ecbc383d4e76438eb6ec5c421a332..2bea127e8113a32f216ae7a7201e36a6e7c56cc2 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 657b07cb721ecbc383d4e76438eb6ec5c421a332
+Subproject commit 2bea127e8113a32f216ae7a7201e36a6e7c56cc2
diff --git a/default.nix b/default.nix
new file mode 100644
index 0000000000000000000000000000000000000000..fbaa668f01276bc0ce0ae3aad44fe15dd8654fad
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,42 @@
+{
+  lib,
+  stdenv,
+  cmake,
+  hpp-core,
+  hpp-universal-robot,
+}:
+
+stdenv.mkDerivation {
+  pname = "hpp-manipulation";
+  version = "5.0.0";
+
+  src = lib.fileset.toSource {
+    root = ./.;
+    fileset = lib.fileset.unions [
+      ./CMakeLists.txt
+      ./doc
+      ./include
+      ./package.xml
+      ./plugins
+      ./src
+      ./tests
+    ];
+  };
+
+  strictDeps = true;
+
+  nativeBuildInputs = [ cmake ];
+  propagatedBuildInputs = [
+    hpp-core
+    hpp-universal-robot
+  ];
+
+  doCheck = true;
+
+  meta = {
+    description = "Classes for manipulation planning";
+    homepage = "https://github.com/humanoid-path-planner/hpp-manipulation";
+    license = lib.licenses.bsd2;
+    maintainers = [ lib.maintainers.nim65s ];
+  };
+}
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000000000000000000000000000000000000..c03e5d0fd003d8b8bbf36b55f516b115c2065477
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,251 @@
+{
+  "nodes": {
+    "flake-parts": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719877454,
+        "narHash": "sha256-g5N1yyOSsPNiOlFfkuI/wcUjmtah+nxdImJqrSATjOU=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "4e3583423212f9303aa1a6337f8dffb415920e4f",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "hpp-constraints": {
+      "inputs": {
+        "flake-parts": [
+          "hpp-core",
+          "flake-parts"
+        ],
+        "hpp-pinocchio": "hpp-pinocchio",
+        "hpp-statistics": "hpp-statistics",
+        "hpp-util": "hpp-util",
+        "nixpkgs": [
+          "hpp-core",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719584695,
+        "narHash": "sha256-8K94IgUt8kpdRDASnstfX14cBQN4ZK6+LmvOuq6Sg0I=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-constraints",
+        "rev": "acd1c62fdfcdb329fd0dea19ae2f18e471e3ef08",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "ref": "release/5.1.0",
+        "repo": "hpp-constraints",
+        "type": "github"
+      }
+    },
+    "hpp-core": {
+      "inputs": {
+        "flake-parts": [
+          "flake-parts"
+        ],
+        "hpp-constraints": "hpp-constraints",
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719770669,
+        "narHash": "sha256-GzlQ4kfiMUf9qVP5t+/qoQZbBIOe1JPdmL7+86dJVaQ=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-core",
+        "rev": "5aa007c687c080608c9864d239f523d452bd7181",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-core",
+        "type": "github"
+      }
+    },
+    "hpp-environments": {
+      "inputs": {
+        "flake-parts": [
+          "hpp-core",
+          "hpp-constraints",
+          "hpp-pinocchio",
+          "flake-parts"
+        ],
+        "nixpkgs": [
+          "hpp-core",
+          "hpp-constraints",
+          "hpp-pinocchio",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719580427,
+        "narHash": "sha256-T76zgTJrGm7maKBPwgX+FgQ7MPN7NoLvdZvzARPo9V0=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-environments",
+        "rev": "1c727bcc85145a1f5236357fa73df5a183a31f04",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "ref": "release/5.1.0",
+        "repo": "hpp-environments",
+        "type": "github"
+      }
+    },
+    "hpp-pinocchio": {
+      "inputs": {
+        "flake-parts": [
+          "hpp-core",
+          "hpp-constraints",
+          "flake-parts"
+        ],
+        "hpp-environments": "hpp-environments",
+        "hpp-util": [
+          "hpp-core",
+          "hpp-constraints",
+          "hpp-util"
+        ],
+        "nixpkgs": [
+          "hpp-core",
+          "hpp-constraints",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719582071,
+        "narHash": "sha256-sRWf973UZIdyrS0fhd+vXdTucR9d7Eks9yU85kcFxfo=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-pinocchio",
+        "rev": "4ec6186223ce18f4c48605421a7ef583fe827352",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "ref": "release/5.1.0",
+        "repo": "hpp-pinocchio",
+        "type": "github"
+      }
+    },
+    "hpp-statistics": {
+      "inputs": {
+        "flake-parts": [
+          "hpp-core",
+          "hpp-constraints",
+          "flake-parts"
+        ],
+        "hpp-util": [
+          "hpp-core",
+          "hpp-constraints",
+          "hpp-util"
+        ],
+        "nixpkgs": [
+          "hpp-core",
+          "hpp-constraints",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719582334,
+        "narHash": "sha256-bzGI7z6hTGkuNs71Vcb3vsVpey1SuR7Okx4rJU1LHFs=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-statistics",
+        "rev": "613b1f9c2788cb33097c1f1c0e4216420665a1e0",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "ref": "release/5.1.0",
+        "repo": "hpp-statistics",
+        "type": "github"
+      }
+    },
+    "hpp-universal-robot": {
+      "inputs": {
+        "flake-parts": [
+          "flake-parts"
+        ],
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719769533,
+        "narHash": "sha256-Fyq7P+YZDGUKxOrif0id1WIeMKu5o/7FM+CRpBCPC2A=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-universal-robot",
+        "rev": "789a540f150b7dc50f3409d94338b7aa96f74084",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-universal-robot",
+        "type": "github"
+      }
+    },
+    "hpp-util": {
+      "inputs": {
+        "flake-parts": [
+          "hpp-core",
+          "hpp-constraints",
+          "flake-parts"
+        ],
+        "nixpkgs": [
+          "hpp-core",
+          "hpp-constraints",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1719580825,
+        "narHash": "sha256-trfl8A+P7a1gnACnTXNK98TYWWDAOM3PKfkXxpC3X/8=",
+        "owner": "humanoid-path-planner",
+        "repo": "hpp-util",
+        "rev": "0504f15818a92c7a257cd6b60cd8b6092bd6dbfa",
+        "type": "github"
+      },
+      "original": {
+        "owner": "humanoid-path-planner",
+        "ref": "release/5.1.0",
+        "repo": "hpp-util",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1719674427,
+        "narHash": "sha256-z2hCpVyfnmYTA5iabf1SW4peFV9itE1JJcXNBKIFkDg=",
+        "owner": "nim65s",
+        "repo": "nixpkgs",
+        "rev": "b81610d293fac26c2ec6a81718a979bc25f8c155",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nim65s",
+        "ref": "gepetto",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-parts": "flake-parts",
+        "hpp-core": "hpp-core",
+        "hpp-universal-robot": "hpp-universal-robot",
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000000000000000000000000000000000000..b2c1c393e825c8ae1c6056752500e3a29393842a
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,55 @@
+{
+  description = "Classes for manipulation planning";
+
+  nixConfig = {
+    extra-substituters = [ "https://gepetto.cachix.org" ];
+    extra-trusted-public-keys = [ "gepetto.cachix.org-1:toswMl31VewC0jGkN6+gOelO2Yom0SOHzPwJMY2XiDY=" ];
+  };
+
+  inputs = {
+    nixpkgs.url = "github:nim65s/nixpkgs/gepetto";
+    flake-parts = {
+      url = "github:hercules-ci/flake-parts";
+      inputs.nixpkgs-lib.follows = "nixpkgs";
+    };
+    hpp-core = {
+      url = "github:humanoid-path-planner/hpp-core";
+      inputs.nixpkgs.follows = "nixpkgs";
+      inputs.flake-parts.follows = "flake-parts";
+    };
+    hpp-universal-robot = {
+      url = "github:humanoid-path-planner/hpp-universal-robot";
+      inputs.nixpkgs.follows = "nixpkgs";
+      inputs.flake-parts.follows = "flake-parts";
+    };
+  };
+
+  outputs =
+    inputs@{ flake-parts, ... }:
+    flake-parts.lib.mkFlake { inherit inputs; } {
+      imports = [ ];
+      systems = [
+        "x86_64-linux"
+        "aarch64-linux"
+        "aarch64-darwin"
+        "x86_64-darwin"
+      ];
+      perSystem =
+        {
+          self',
+          pkgs,
+          system,
+          ...
+        }:
+        {
+          packages = {
+            inherit (pkgs) cachix;
+            default = pkgs.callPackage ./. {
+              hpp-core = inputs.hpp-core.packages.${system}.default;
+              hpp-universal-robot = inputs.hpp-universal-robot.packages.${system}.default;
+            };
+          };
+          devShells.default = pkgs.mkShell { inputsFrom = [ self'.packages.default ]; };
+        };
+    };
+}
diff --git a/package.xml b/package.xml
index 2037746a27a9afb8cec23d4603425ebba00d1cf3..90cc3ed56719d6fbffde09d7c6b7597aa9c0cf69 100644
--- a/package.xml
+++ b/package.xml
@@ -1,7 +1,7 @@
 <?xml version='1.0'?>
  <package format='2'>
  <name>hpp-manipulation</name>
- <version>5.0.0</version>
+ <version>5.1.0</version>
  <description>Classes for manipulation planning. </description>
 
  <maintainer email='hpp@laas.fr'>Joseph Mirabel</maintainer>
diff --git a/pyproject.toml b/pyproject.toml
index a5333a8b34f59be815cc36db7c829347b3b3578e..a68d75e5a3a1538680ab8afc93658df828064be3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -14,7 +14,7 @@ dependencies = [
 description = "Classes for manipulation planning."
 license = "BSD-2-Clause"
 name = "hpp-manipulation"
-version = "5.0.0"
+version = "5.1.0"
 
 [tool.ruff]
 extend-exclude = ["cmake"]