diff --git a/Cargo.lock b/Cargo.lock
index 0079321be3..ce4db3af9d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2550,14 +2550,15 @@ dependencies = [
 [[package]]
 name = "keyboard-keynames"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6dbe132877d7a0327c4282840703c2cb456312fae930898b5dc126844889626"
+source = "git+https://gitlab.com/Frinksy/keyboard-keynames.git?rev=a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c#a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c"
 dependencies = [
+ "libc",
+ "memmap",
  "wayland-client 0.28.5",
  "winapi 0.3.9",
  "winit",
- "xcb 0.8.2",
- "xkbcommon",
+ "xcb",
+ "xkbcommon-sys 0.7.5",
 ]
 
 [[package]]
@@ -2872,7 +2873,7 @@ dependencies = [
  "winapi 0.3.9",
  "x11-dl",
  "xkb",
- "xkbcommon-sys",
+ "xkbcommon-sys 0.7.4",
 ]
 
 [[package]]
@@ -6483,7 +6484,7 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5e937afd03b64b7be4f959cc044e09260a47241b71e56933f37db097bf7859d"
 dependencies = [
- "xcb 0.9.0",
+ "xcb",
 ]
 
 [[package]]
@@ -6519,16 +6520,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "xcb"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de"
-dependencies = [
- "libc",
- "log",
-]
-
 [[package]]
 name = "xcb"
 version = "0.9.0"
@@ -6568,18 +6559,7 @@ checksum = "aec02bc5de902aa579f3d2f2c522edaf40fa42963cbaffe645b058ddcc68fdb2"
 dependencies = [
  "bitflags",
  "libc",
- "xkbcommon-sys",
-]
-
-[[package]]
-name = "xkbcommon"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fda0ea5f7ddabd51deeeda7799bee06274112f577da7dd3d954b8eda731b2fce"
-dependencies = [
- "libc",
- "memmap",
- "xcb 0.8.2",
+ "xkbcommon-sys 0.7.4",
 ]
 
 [[package]]
@@ -6592,6 +6572,15 @@ dependencies = [
  "pkg-config",
 ]
 
+[[package]]
+name = "xkbcommon-sys"
+version = "0.7.5"
+source = "git+https://github.com/Frinksy/rust-xkbcommon-sys.git?rev=d5d69e05a81f7ee8d2f65a824ae692610ed7cb14#d5d69e05a81f7ee8d2f65a824ae692610ed7cb14"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
 [[package]]
 name = "xml-rs"
 version = "0.8.3"
diff --git a/Cargo.toml b/Cargo.toml
index 4ef02f3feb..817eb35f37 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -96,3 +96,13 @@ debug = 1
 # macos CI fix isn't merged yet
 winit = { git = "https://gitlab.com/veloren/winit.git", branch = "macos-test-spiffed" }
 vek = { git = "https://gitlab.com/veloren/vek.git", branch = "fix_intrinsics2" }
+
+[workspace.metadata.nix]
+systems = ["x86_64-linux"]
+buildInputs = ["libudev", "alsaLib", "openssl", "xorg.libxcb", "libxkbcommon"]
+nativeBuildInputs = ["pkg-config", "python3", "binutils"]
+runtimeLibs = ["libGL", "xorg.libX11", "xorg.libXcursor", "xorg.libXrandr", "xorg.libXi"]
+
+[workspace.metadata.nix.cachix]
+name = "veloren-nix"
+key = "veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc="
diff --git a/flake.lock b/flake.lock
index c221ca1ffc..640c2acb74 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,5 +1,20 @@
 {
   "nodes": {
+    "devshell": {
+      "locked": {
+        "lastModified": 1618213758,
+        "narHash": "sha256-qkuen2xlT7gVfX+99OeM4lsKXGjT5EDjytWAeAWX0Fw=",
+        "owner": "numtide",
+        "repo": "devshell",
+        "rev": "eac56f015b0975be3b725721503626e926b285e8",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "devshell",
+        "type": "github"
+      }
+    },
     "flake-utils": {
       "locked": {
         "lastModified": 1614513358,
@@ -37,11 +52,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1616263753,
-        "narHash": "sha256-wf1naH44D0Z7+JNpD6T/6/d0XaXDi9r4Oi100pBtzhs=",
+        "lastModified": 1618579991,
+        "narHash": "sha256-aIWvSjn/rjfOBUdL5uM4iDVVLM7ioRz9zs3e94lT9Ac=",
         "owner": "yusdacra",
         "repo": "naersk",
-        "rev": "8cd4d175606de222114c551c85847acb013cc9cb",
+        "rev": "dc8868af09c8a0f0d47df0927161cb14675c5534",
         "type": "github"
       },
       "original": {
@@ -51,13 +66,39 @@
         "type": "github"
       }
     },
+    "nixCargoIntegration": {
+      "inputs": {
+        "devshell": "devshell",
+        "flakeUtils": "flakeUtils",
+        "naersk": [
+          "naersk"
+        ],
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "rustOverlay": "rustOverlay"
+      },
+      "locked": {
+        "lastModified": 1618597947,
+        "narHash": "sha256-wiwHpQPzgkuOEZXFpet7bmv6Z8dusxyp6DQbpYCXJDk=",
+        "owner": "yusdacra",
+        "repo": "nix-cargo-integration",
+        "rev": "fc26a4e1d807e8b9722d67097be4dfb8be5ea862",
+        "type": "github"
+      },
+      "original": {
+        "owner": "yusdacra",
+        "repo": "nix-cargo-integration",
+        "type": "github"
+      }
+    },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1618306168,
-        "narHash": "sha256-/IOtgzdEaiEqRVn6OhpekuYhRHfCm299Bqts5QqQVko=",
+        "lastModified": 1618530127,
+        "narHash": "sha256-jQPk7XpabppYa+GIO5LVTtUFhHq/VqHhPggwIKhTCnQ=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "4c87cb87a2db6b9eb43541c1cf83f2a2f725fa25",
+        "rev": "294d1925af6462e55c76b49624b983036f0093b9",
         "type": "github"
       },
       "original": {
@@ -69,10 +110,9 @@
     },
     "root": {
       "inputs": {
-        "flakeUtils": "flakeUtils",
         "naersk": "naersk",
-        "nixpkgs": "nixpkgs",
-        "rustOverlay": "rustOverlay"
+        "nixCargoIntegration": "nixCargoIntegration",
+        "nixpkgs": "nixpkgs"
       }
     },
     "rustOverlay": {
diff --git a/flake.nix b/flake.nix
index a3da8209af..37eb2641f3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -6,56 +6,97 @@
       url = "github:yusdacra/naersk/veloren";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-    flakeUtils.url = "github:numtide/flake-utils";
-    rustOverlay = {
-      url = "github:oxalica/rust-overlay";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
     nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+    nixCargoIntegration = {
+      url = "github:yusdacra/nix-cargo-integration";
+      inputs.nixpkgs.follows = "nixpkgs";
+      inputs.naersk.follows = "naersk";
+    };
   };
 
-  outputs = inputs: with inputs; with flakeUtils.lib;
-    eachSystem [ "x86_64-linux" ] (system:
-      let
-        common = import ./nix/common.nix {
-          sources = {
-            inherit
-              naersk
-              nixpkgs
-              rustOverlay
-              ;
+  outputs = inputs:
+    let
+      output = inputs.nixCargoIntegration.lib.makeOutputs {
+        root = ./.;
+        overrides = {
+          common = prev: {
+            gitLfsCheckFile = ./assets/voxygen/background/bg_main.png;
+            utils = import ./nix/utils.nix { pkgs = prev.pkgs; };
           };
-          inherit system;
+          build = common: prevb:
+            let
+              pkgs = common.pkgs;
+              sourceInfo =
+                if inputs.self.sourceInfo ? rev
+                then inputs.self.sourceInfo // {
+                  # Tag would have to be set manually for stable releases flake
+                  # because there's currently no way to get the tag via the interface.
+                  # tag = v0.9.0;
+                }
+                else (throw "Can't get revision because the git tree is dirty");
+
+              prettyRev = with sourceInfo; builtins.substring 0 8 rev + "/" + common.utils.dateTimeFormat lastModified;
+
+              tag = with sourceInfo;
+                if sourceInfo ? tag
+                then sourceInfo.tag
+                else "";
+
+              # If gitTag has a tag (meaning the commit we are on is a *release*), use
+              # it as version, else: just use the prettified hash we have, if we don't
+              # have it the build fails.
+              # Must be in format f4987672/2020-12-10-12:00
+              version =
+                if tag != "" then tag
+                else if prettyRev != "" then prettyRev
+                else throw "Need a tag or pretty revision in order to determine version";
+
+              veloren-assets = pkgs.runCommand "makeAssetsDir" { } ''
+                mkdir $out
+                ln -sf ${./assets} $out/assets
+              '';
+
+              velorenOverride = oldAttr:
+                if common.cargoPkg.name == "veloren-voxygen"
+                then
+                  {
+                    nativeBuildInputs = oldAttr.nativeBuildInputs ++ [ pkgs.makeWrapper ];
+                    postInstall = ''
+                      wrapProgram $out/bin/veloren-voxygen\
+                        --set VELOREN_ASSETS ${veloren-assets}\
+                        --set LD_LIBRARY_PATH ${
+                          pkgs.lib.makeLibraryPath common.runtimeLibs
+                        }
+                    '';
+                  }
+                else if common.cargoPkg.name == "veloren-server-cli"
+                then
+                  {
+                    nativeBuildInputs = oldAttr.nativeBuildInputs ++ [ pkgs.makeWrapper ];
+                    postInstall = ''
+                      wrapProgram $out/bin/veloren-server-cli --set VELOREN_ASSETS ${veloren-assets}
+                    '';
+                  }
+                else { };
+            in
+            {
+              allRefs = true;
+              override = old: (prevb.override old) // {
+                # Disable `git-lfs` check here since we check it ourselves
+                # We have to include the command output here, otherwise Nix won't run it
+                DISABLE_GIT_LFS_CHECK = common.utils.isGitLfsSetup common.gitLfsCheckFile;
+                # Declare env values here so that `common/build.rs` sees them
+                NIX_GIT_HASH = prettyRev;
+                NIX_GIT_TAG = tag;
+                VELOREN_USERDATA_STRATEGY = "system";
+              };
+              overrideMain = old: (prevb.overrideMain old) // (velorenOverride old);
+            };
         };
-
-        mkPackage = crateName: import ./nix/build.nix {
-          inherit common;
-          crateToBuild = crateName;
-          sourceInfo =
-            if self.sourceInfo ? rev
-            then self.sourceInfo // {
-              # Tag would have to be set manually for stable releases flake
-              # because there's currently no way to get the tag via the interface.
-              # tag = v0.8.0;
-            }
-            else (throw "Can't get revision because the git tree is dirty");
-        };
-
-        cratesToPackage = [ "veloren-voxygen" "veloren-server-cli" ];
-
-        genAttrs = names: f:
-          builtins.listToAttrs (map (n: { name = n; value = f n; }) names);
-      in
-      rec {
-        packages = genAttrs cratesToPackage mkPackage;
-        defaultPackage = packages.veloren-voxygen;
-
-        apps = builtins.mapAttrs (n: v: mkApp { name = n; drv = v; }) packages;
-        defaultApp = apps.veloren-voxygen;
-
-        devShell = import ./nix/devShell.nix {
-          inherit common;
-        };
-      }
-    );
+      };
+    in
+    output // {
+      defaultApp = builtins.mapAttrs (_: apps: apps.veloren-voxygen-debug) output.apps;
+      defaultPackage = builtins.mapAttrs (_: packages: packages.veloren-voxygen-debug) output.packages;
+    };
 }
diff --git a/nix/build.nix b/nix/build.nix
deleted file mode 100644
index ef83e385dd..0000000000
--- a/nix/build.nix
+++ /dev/null
@@ -1,118 +0,0 @@
-{ common
-, release ? true
-, crateToBuild ? "veloren-voxygen"
-, disableGitLfsCheck ? false
-, sourceInfo ? { }
-}:
-with common;
-let
-  utils = import ./utils.nix { inherit pkgs; };
-
-  meta = with pkgs.lib; {
-    description = "Veloren is a multiplayer voxel RPG written in Rust.";
-    longDescription = ''
-      Veloren is a multiplayer voxel RPG written in Rust.
-      It is inspired by games such as Cube World, Legend of Zelda: Breath of the Wild, Dwarf Fortress and Minecraft.
-    '';
-    homepage = "https://veloren.net";
-    license = licenses.gpl3;
-    maintainers = [ maintainers.yusdacra ];
-    # TODO: Make this work on BSD and Mac OS
-    platforms = platforms.linux;
-  };
-
-  prettyRev = with sourceInfo; builtins.substring 0 8 rev + "/" + utils.dateTimeFormat lastModified;
-
-  tag = with sourceInfo;
-    if sourceInfo ? tag
-    then sourceInfo.tag
-    else "";
-
-  # If gitTag has a tag (meaning the commit we are on is a *release*), use
-  # it as version, else: just use the prettified hash we have, if we don't
-  # have it the build fails.
-  # Must be in format f4987672/2020-12-10-12:00
-  version =
-    if tag != "" then tag
-    else if prettyRev != "" then prettyRev
-    else throw "Need a tag or pretty revision in order to determine version";
-
-  veloren-assets = pkgs.runCommand "makeAssetsDir" { } ''
-    mkdir $out
-    ln -sf ${../assets} $out/assets
-  '';
-
-  velorenVoxygenDesktopFile = pkgs.makeDesktopItem rec {
-    name = "veloren-voxygen";
-    exec = name;
-    icon = ../assets/voxygen/logo.ico;
-    comment =
-      "Official client for Veloren - the open-world, open-source multiplayer voxel RPG";
-    desktopName = "Voxygen";
-    genericName = "Veloren Client";
-    categories = "Game;";
-  };
-
-  velorenOverride = oldAttr: with pkgs;
-    if crateToBuild == "veloren-voxygen"
-    then
-      {
-        pname = "veloren-voxygen";
-        inherit version;
-
-        nativeBuildInputs = (oldAttr.nativeBuildInputs or [ ]) ++ [ makeWrapper copyDesktopItems ];
-        desktopItems = [ velorenVoxygenDesktopFile ];
-        postInstall = ''
-          wrapProgram $out/bin/veloren-voxygen\
-            --set VELOREN_ASSETS ${veloren-assets}\
-            --set LD_LIBRARY_PATH ${
-              lib.makeLibraryPath common.voxygenNeededLibs
-            }
-        '';
-        meta = meta // {
-          longDescription = ''
-            ${meta.longDescription}
-            "This package includes the official client, Voxygen."
-          '';
-        };
-      }
-    else if crateToBuild == "veloren-server-cli"
-    then
-      {
-        pname = "veloren-server-cli";
-        inherit version;
-
-        nativeBuildInputs = (oldAttr.nativeBuildInputs or [ ]) ++ [ makeWrapper ];
-        postInstall = ''
-          wrapProgram $out/bin/veloren-server-cli --set VELOREN_ASSETS ${veloren-assets}
-        '';
-        meta = meta // {
-          longDescription = ''
-            ${meta.longDescription}
-            "This package includes the server CLI."
-          '';
-        };
-      }
-    else { };
-
-  velorenPackage =
-    pkgs.naersk.buildPackage {
-      name = crateToBuild;
-      root = ../.;
-      targets = [ crateToBuild ];
-      nativeBuildInputs = common.crateDeps.nativeBuildInputs;
-      buildInputs = common.crateDeps.buildInputs;
-      override = (_: {
-        # Disable `git-lfs` check here since we check it ourselves
-        # We have to include the command output here, otherwise Nix won't run it
-        DISABLE_GIT_LFS_CHECK = utils.isGitLfsSetup common.gitLfsCheckFile;
-        # Declare env values here so that `common/build.rs` sees them
-        NIX_GIT_HASH = prettyRev;
-        NIX_GIT_TAG = tag;
-        VELOREN_USERDATA_STRATEGY = "system";
-      });
-      overrideMain = velorenOverride;
-      inherit release;
-    };
-in
-velorenPackage
diff --git a/nix/common.nix b/nix/common.nix
deleted file mode 100644
index bdc417469b..0000000000
--- a/nix/common.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{ sources, system }:
-let
-  pkgz = import sources.nixpkgs { inherit system; overlays = [ sources.rustOverlay.overlay ]; };
-  rust = (pkgz.rust-bin.fromRustupToolchainFile ../rust-toolchain).override {
-    extensions = [ "rust-src" ];
-  };
-
-  pkgs = import sources.nixpkgs {
-    inherit system;
-    overlays = [
-      (final: prev: {
-        rustc = rust;
-      })
-      (final: prev: {
-        naersk = prev.callPackage sources.naersk { };
-      })
-    ];
-  };
-in
-with pkgs;
-{
-  inherit pkgs;
-  # deps that crates need (for compiling)
-  crateDeps =
-    {
-      nativeBuildInputs = [ pkg-config python3 ];
-      buildInputs = [ libudev alsaLib openssl xorg.libxcb ];
-    };
-  # deps that voxygen needs to function
-  # FIXME: Wayland doesn't work (adding libxkbcommon, wayland and wayland-protocols results in a panic)
-  voxygenNeededLibs = (with xorg; [ libX11 libXcursor libXrandr libXi ])
-    ++ [ libGL ];
-  gitLfsCheckFile = ../assets/voxygen/background/bg_main.png;
-}
diff --git a/nix/devShell.nix b/nix/devShell.nix
deleted file mode 100644
index 7a17c3aaa4..0000000000
--- a/nix/devShell.nix
+++ /dev/null
@@ -1,25 +0,0 @@
-{ common }:
-with common; with pkgs;
-mkShell {
-  name = "veloren-shell";
-  nativeBuildInputs = [
-    cachix
-    git
-    git-lfs
-    nixpkgs-fmt
-    rustc
-  ] ++ crateDeps.nativeBuildInputs;
-  buildInputs = crateDeps.buildInputs;
-  shellHook = ''
-    # Setup our cachix "substituter"
-    export NIX_CONFIG="
-      substituters = https://cache.nixos.org https://veloren-nix.cachix.org
-      trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc=
-    "
-    # Add libraries Voxygen needs so that it runs
-    export LD_LIBRARY_PATH=${lib.makeLibraryPath voxygenNeededLibs}
-
-    # No need to install git-lfs and run fetch / checkout commands if we have it setup
-    [ "$(${file}/bin/file --mime-type ${gitLfsCheckFile})" = "${gitLfsCheckFile}: image/png" ] || (git lfs install --local && git lfs fetch && git lfs checkout)
-  '';
-}
diff --git a/nix/envrc b/nix/envrc
index c258f265aa..9777841235 100644
--- a/nix/envrc
+++ b/nix/envrc
@@ -1,7 +1,5 @@
 watch_file flake.lock
 watch_file flake.nix
-watch_file nix/common.nix
-watch_file nix/devShell.nix
 watch_file nix/shell.nix
 watch_file nix/utils.nix
 
diff --git a/nix/utils.nix b/nix/utils.nix
index bea5c91bad..d6ce5b648f 100644
--- a/nix/utils.nix
+++ b/nix/utils.nix
@@ -16,6 +16,8 @@
           - This repository was not cloned from the primary GitLab mirror.
           - The GitHub mirror does not support LFS.
         See the book at https://book.veloren.net/ for details.
+        Run `nix-shell -p git git-lfs --run "git lfs install --local && git lfs fetch && git lfs checkout"`
+        or `nix shell nixpkgs#git-lfs nixpkgs#git -c sh -c "git lfs install --local && git lfs fetch && git lfs checkout"`.
       '';
 
   # Format number of seconds in the Unix epoch as %Y-%m-%d-%H:%M.
diff --git a/server-cli/Cargo.toml b/server-cli/Cargo.toml
index 3fa9f0c894..6041be5e66 100644
--- a/server-cli/Cargo.toml
+++ b/server-cli/Cargo.toml
@@ -4,6 +4,16 @@ version = "0.9.0"
 authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
 edition = "2018"
 
+[package.metadata.nix]
+build = true
+app = true
+longDescription = """
+Veloren is a multiplayer voxel RPG written in Rust.
+It is inspired by games such as Cube World, Legend of Zelda: Breath of the Wild, Dwarf Fortress and Minecraft.
+
+This package includes the official server CLI.
+"""
+
 [features]
 worldgen = ["server/worldgen"]
 default = ["worldgen"]
diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml
index 06cbf713a5..abf119b046 100644
--- a/voxygen/Cargo.toml
+++ b/voxygen/Cargo.toml
@@ -8,6 +8,17 @@ version = "0.9.0"
 # Uncomment below and comment out default-run if you want to avoid this
 # autobins = false
 
+[package.metadata.nix]
+build = true
+app = true
+desktopFile = "./assets/voxygen/net.veloren.veloren.desktop"
+longDescription = """
+Veloren is a multiplayer voxel RPG written in Rust.
+It is inspired by games such as Cube World, Legend of Zelda: Breath of the Wild, Dwarf Fortress and Minecraft.
+
+This package includes the official client, Voxygen.
+"""
+
 [features]
 gl = ["gfx_device_gl", "gfx_gl"]
 hot-anim = ["anim/use-dyn-lib"]
@@ -45,7 +56,7 @@ iced = {package = "iced_native", git = "https://github.com/hecrj/iced", rev = "8
 iced_winit = {git = "https://github.com/hecrj/iced", rev = "8d882d787e6b7fd7c2435f42f82933e2ed904edf"}
 window_clipboard = "0.2"
 glyph_brush = "0.7.0"
-keyboard-keynames = "0.1.0"
+keyboard-keynames = { git = "https://gitlab.com/Frinksy/keyboard-keynames.git", rev = "a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c" }
 
 # ECS
 specs = {git = "https://github.com/amethyst/specs.git", rev = "5a9b71035007be0e3574f35184acac1cd4530496"}