diff --git a/doc/languages-frameworks/dotnet.section.md b/doc/languages-frameworks/dotnet.section.md
index cdacec1c3a5e..2cbb7ea45d98 100644
--- a/doc/languages-frameworks/dotnet.section.md
+++ b/doc/languages-frameworks/dotnet.section.md
@@ -93,7 +93,7 @@ The `dotnetCorePackages.sdk` contains both a runtime and the full sdk of a given
 To package Dotnet applications, you can use `buildDotnetModule`. This has similar arguments to `stdenv.mkDerivation`, with the following additions:
 
 * `projectFile` is used for specifying the dotnet project file, relative to the source root. These have `.sln` (entire solution) or `.csproj` (single project) file extensions. This can be a list of multiple projects as well. When omitted, will attempt to find and build the solution (`.sln`). If running into problems, make sure to set it to a file (or a list of files) with the `.csproj` extension - building applications as entire solutions is not fully supported by the .NET CLI.
-* `nugetDeps` takes either a path to a `deps.nix` file, or a derivation. The `deps.nix` file can be generated using the script attached to `passthru.fetch-deps`. If the argument is a derivation, it will be used directly and assume it has the same output as `mkNugetDeps`.
+* `nugetDeps` takes either a path to a `deps.nix` file, or a derivation. The `deps.nix` file can be generated using the script attached to `passthru.fetch-deps`. For compatibility, if the argument is a list of derivations, they will be added to `buildInputs`.
 ::: {.note}
 For more detail about managing the `deps.nix` file, see [Generating and updating NuGet dependencies](#generating-and-updating-nuget-dependencies)
 :::
diff --git a/maintainers/scripts/update-dotnet-lockfiles.nix b/maintainers/scripts/update-dotnet-lockfiles.nix
index 22ceff1ffa99..a79b0b074c8d 100644
--- a/maintainers/scripts/update-dotnet-lockfiles.nix
+++ b/maintainers/scripts/update-dotnet-lockfiles.nix
@@ -10,7 +10,7 @@
   update scripts.
  */
 let
-  pkgs = import ../.. {};
+  pkgs = import ../.. { config.allowAliases = false; };
 
   inherit (pkgs) lib;
 
diff --git a/pkgs/applications/audio/openutau/default.nix b/pkgs/applications/audio/openutau/default.nix
index 3e16c7b512de..f797215b607b 100644
--- a/pkgs/applications/audio/openutau/default.nix
+++ b/pkgs/applications/audio/openutau/default.nix
@@ -5,9 +5,6 @@
 , dotnetCorePackages
 , dbus
 , fontconfig
-, libICE
-, libSM
-, libX11
 , portaudio
 }:
 
@@ -32,10 +29,6 @@ buildDotnetModule rec {
 
   runtimeDeps = [
     dbus
-    fontconfig
-    libICE
-    libSM
-    libX11
     portaudio
   ];
 
diff --git a/pkgs/applications/version-management/git-credential-manager/default.nix b/pkgs/applications/version-management/git-credential-manager/default.nix
index 592074224f01..c9df6aff549a 100644
--- a/pkgs/applications/version-management/git-credential-manager/default.nix
+++ b/pkgs/applications/version-management/git-credential-manager/default.nix
@@ -2,22 +2,16 @@
 , fetchFromGitHub
 , buildDotnetModule
 , dotnetCorePackages
-, libX11
-, libICE
-, libSM
-, fontconfig
 , libsecret
 , git
 , git-credential-manager
 , gnupg
 , pass
 , testers
-, withGuiSupport ? true
 , withLibsecretSupport ? true
 , withGpgSupport ? true
 }:
 
-assert withLibsecretSupport -> withGuiSupport;
 buildDotnetModule rec {
   pname = "git-credential-manager";
   version = "2.5.1";
@@ -36,9 +30,8 @@ buildDotnetModule rec {
   dotnetInstallFlags = [ "--framework" "net8.0" ];
   executables = [ "git-credential-manager" ];
 
-  runtimeDeps = [ fontconfig ]
-    ++ lib.optionals withGuiSupport [ libX11 libICE libSM ]
-    ++ lib.optional withLibsecretSupport libsecret;
+  runtimeDeps =
+    lib.optional withLibsecretSupport libsecret;
   makeWrapperArgs = [
     "--prefix PATH : ${lib.makeBinPath ([ git ] ++ lib.optionals withGpgSupport [ gnupg pass ])}"
   ];
diff --git a/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix b/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix
index 466c1972899c..2177000c3627 100644
--- a/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix
+++ b/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix
@@ -1,4 +1,4 @@
-{ buildDotnetModule, emptyDirectory, mkNugetDeps, dotnet-sdk }:
+{ buildDotnetModule, emptyDirectory, fetchNupkg, dotnet-sdk }:
 
 { pname
 , version
@@ -23,13 +23,15 @@ buildDotnetModule (args // {
 
   src = emptyDirectory;
 
-  nugetDeps = mkNugetDeps {
-    name = pname;
-    nugetDeps = { fetchNuGet }: [
-      (fetchNuGet { pname = nugetName; inherit version; sha256 = nugetSha256; hash = nugetHash; })
-    ] ++ (nugetDeps fetchNuGet);
-    installable = true;
-  };
+  buildInputs = [
+    (fetchNupkg {
+      pname = nugetName;
+      inherit version;
+      sha256 = nugetSha256;
+      hash = nugetHash;
+      installable = true;
+    })
+  ];
 
   dotnetGlobalTool = true;
 
diff --git a/pkgs/build-support/dotnet/build-dotnet-module/default.nix b/pkgs/build-support/dotnet/build-dotnet-module/default.nix
index e36e339dfa7f..412747733bd6 100644
--- a/pkgs/build-support/dotnet/build-dotnet-module/default.nix
+++ b/pkgs/build-support/dotnet/build-dotnet-module/default.nix
@@ -7,7 +7,7 @@
   writeShellScript,
   makeWrapper,
   dotnetCorePackages,
-  mkNugetDeps,
+  fetchNupkg,
   nuget-to-nix,
   cacert,
   unzip,
@@ -18,10 +18,7 @@ let
   transformArgs =
     finalAttrs:
     {
-      name ? "${args.pname}-${args.version}",
-      pname ? name,
       enableParallelBuilding ? true,
-      doCheck ? false,
       # Flags to pass to `makeWrapper`. This is done to avoid double wrapping.
       makeWrapperArgs ? [ ],
 
@@ -115,22 +112,36 @@ let
       _nugetDeps =
         if (nugetDeps != null) then
           if lib.isDerivation nugetDeps then
+            [ nugetDeps ]
+          else if lib.isList nugetDeps then
             nugetDeps
           else
-            mkNugetDeps {
-              inherit name;
-              sourceFile = nugetDeps;
-            }
+            assert (lib.isPath nugetDeps);
+            callPackage nugetDeps { fetchNuGet = fetchNupkg; }
         else
-          throw "Defining the `nugetDeps` attribute is required, as to lock the NuGet dependencies. This file can be generated by running the `passthru.fetch-deps` script.";
+          [ ];
 
-      nugetDepsFile = _nugetDeps.sourceFile;
+      nugetDepsFile = if lib.isPath nugetDeps then nugetDeps else null;
 
       inherit (dotnetCorePackages) systemToDotnetRid;
     in
     # Not all args need to be passed through to mkDerivation
     # TODO: We should probably filter out even more attrs
-    removeAttrs args [ "nugetDeps" ]
+    removeAttrs args [
+      "nugetDeps"
+      "installPath"
+      "executables"
+      "projectFile"
+      "projectReferences"
+      "runtimeDeps"
+      "runtimeId"
+      "disabledTests"
+      "testProjectFile"
+      "buildType"
+      "selfContainedBuild"
+      "useDotnet"
+      "useAppHost"
+    ]
     // {
       dotnetInstallPath = installPath;
       dotnetExecutables = executables;
@@ -145,9 +156,18 @@ let
       dotnetRuntimeDeps = map lib.getLib runtimeDeps;
       dotnetSelfContainedBuild = selfContainedBuild;
       dotnetUseAppHost = useAppHost;
-      inherit useDotnetFromEnv;
 
-      inherit enableParallelBuilding;
+      inherit
+        enableParallelBuilding
+        dotnetRestoreFlags
+        dotnetBuildFlags
+        dotnetTestFlags
+        dotnetInstallFlags
+        dotnetPackFlags
+        dotnetFlags
+        packNupkg
+        useDotnetFromEnv
+        ;
 
       nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
         dotnetConfigureHook
@@ -163,13 +183,7 @@ let
         yq
       ];
 
-      buildInputs =
-        args.buildInputs or [ ]
-        ++ [
-          dotnet-sdk.packages
-          _nugetDeps
-        ]
-        ++ projectReferences;
+      buildInputs = args.buildInputs or [ ] ++ [ dotnet-sdk.packages ] ++ _nugetDeps ++ projectReferences;
 
       # Parse the version attr into a format acceptable for the Version msbuild property
       # The actual version attr is saved in InformationalVersion, which accepts an arbitrary string
@@ -213,13 +227,13 @@ let
         {
           nugetDeps = _nugetDeps;
         }
-        // lib.optionalAttrs (!lib.isDerivation nugetDeps) {
+        // lib.optionalAttrs (nugetDeps == null || lib.isPath nugetDeps) {
           fetch-deps =
             let
               pkg = finalAttrs.finalPackage.overrideAttrs (
                 old:
                 {
-                  buildInputs = lib.remove _nugetDeps old.buildInputs;
+                  buildInputs = lib.subtractLists _nugetDeps old.buildInputs;
                   keepNugetConfig = true;
                 }
                 // lib.optionalAttrs (runtimeId == null) {
@@ -238,15 +252,15 @@ let
                   # Note that toString is necessary here as it results in the path at
                   # eval time (i.e. to the file in your local Nixpkgs checkout) rather
                   # than the Nix store path of the path after it's been imported.
-                  if lib.isPath nugetDepsFile && !lib.hasPrefix "${builtins.storeDir}/" (toString nugetDepsFile) then
+                  if lib.isPath nugetDeps && !lib.isStorePath nugetDepsFile then
                     toString nugetDepsFile
                   else
-                    ''$(mktemp -t "${pname}-deps-XXXXXX.nix")'';
+                    ''$(mktemp -t "${finalAttrs.pname ? finalAttrs.finalPackage.name}-deps-XXXXXX.nix")'';
                 nugetToNix = (nuget-to-nix.override { inherit dotnet-sdk; });
               };
 
             in
-            writeShellScript "${name}-fetch-deps" ''
+            writeShellScript "${finalAttrs.finalPackage.name}-fetch-deps" ''
               NIX_BUILD_SHELL="${runtimeShell}" exec ${nix}/bin/nix-shell \
                 --pure --run 'source "${innerScript}"' "${drv}"
             '';
diff --git a/pkgs/build-support/dotnet/build-dotnet-module/fetch-deps.sh b/pkgs/build-support/dotnet/build-dotnet-module/fetch-deps.sh
index c8d428240621..ff971ce1e592 100644
--- a/pkgs/build-support/dotnet/build-dotnet-module/fetch-deps.sh
+++ b/pkgs/build-support/dotnet/build-dotnet-module/fetch-deps.sh
@@ -4,6 +4,8 @@ tmp=$(mktemp -d)
 trap 'chmod -R +w "$tmp" && rm -fr "$tmp"' EXIT
 
 HOME=$tmp/.home
+export TMPDIR="$tmp/.tmp"
+mkdir "$HOME" "$TMPDIR"
 cd "$tmp"
 
 phases="
diff --git a/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh b/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
index 1e421cb18ce1..37c815e004e3 100644
--- a/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
+++ b/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
@@ -50,7 +50,7 @@ dotnetConfigureHook() {
         fi
     done
 
-    if [[ -f .config/dotnet-tools.json || -f .dotnet-tools.json ]]; then
+    if [[ -f .config/dotnet-tools.json || -f dotnet-tools.json ]]; then
         dotnet tool restore
     fi
 
diff --git a/pkgs/build-support/dotnet/fetch-nupkg/default.nix b/pkgs/build-support/dotnet/fetch-nupkg/default.nix
new file mode 100644
index 000000000000..07f1f2fc617f
--- /dev/null
+++ b/pkgs/build-support/dotnet/fetch-nupkg/default.nix
@@ -0,0 +1,80 @@
+{
+  symlinkJoin,
+  fetchurl,
+  stdenvNoCC,
+  lib,
+  unzip,
+  patchNupkgs,
+  nugetPackageHook,
+  callPackage,
+  overrides ? callPackage ./overrides.nix { },
+}:
+{
+  pname,
+  version,
+  sha256 ? "",
+  hash ? "",
+  url ? "https://www.nuget.org/api/v2/package/${pname}/${version}",
+  installable ? false,
+}:
+let
+  package = stdenvNoCC.mkDerivation rec {
+    inherit pname version;
+
+    src = fetchurl {
+      name = "${pname}.${version}.nupkg";
+      # There is no need to verify whether both sha256 and hash are
+      # valid here, because nuget-to-nix does not generate a deps.nix
+      # containing both.
+      inherit
+        url
+        sha256
+        hash
+        version
+        ;
+    };
+
+    nativeBuildInputs = [
+      unzip
+      patchNupkgs
+      nugetPackageHook
+    ];
+
+    unpackPhase = ''
+      runHook preUnpack
+
+      unzip -nqd source $src
+      chmod -R +rw source
+      cd source
+
+      runHook postUnpack
+    '';
+
+    prePatch = ''
+      shopt -s nullglob
+      local dir
+      for dir in tools runtimes/*/native; do
+        [[ ! -d "$dir" ]] || chmod -R +x "$dir"
+      done
+      rm -rf .signature.p7s
+    '';
+
+    installPhase = ''
+      runHook preInstall
+
+      dir=$out/share/nuget/packages/${lib.toLower pname}/${lib.toLower version}
+      mkdir -p $dir
+      cp -r . $dir
+      echo {} > "$dir"/.nupkg.metadata
+
+      runHook postInstall
+    '';
+
+    preFixup = ''
+      patch-nupkgs $out/share/nuget/packages
+    '';
+
+    createInstallableNugetSource = installable;
+  };
+in
+overrides.${pname} or lib.id package
diff --git a/pkgs/build-support/dotnet/fetch-nupkg/overrides.nix b/pkgs/build-support/dotnet/fetch-nupkg/overrides.nix
new file mode 100644
index 000000000000..f4bc1976e0eb
--- /dev/null
+++ b/pkgs/build-support/dotnet/fetch-nupkg/overrides.nix
@@ -0,0 +1,55 @@
+{
+  autoPatchelfHook,
+  dotnetCorePackages,
+  fontconfig,
+  lib,
+  libICE,
+  libSM,
+  libX11,
+  stdenv,
+  writeText,
+}:
+{
+  # e.g.
+  # "Package.Id" =
+  #   package:
+  #   package.overrideAttrs (old: {
+  #     buildInputs = old.buildInputs or [ ] ++ [ hello ];
+  #   });
+
+  "Avalonia.X11" =
+    package:
+    package.overrideAttrs (
+      old:
+      lib.optionalAttrs (!stdenv.isDarwin) {
+        setupHook = writeText "setupHook.sh" ''
+          prependToVar dotnetRuntimeDeps \
+            "${lib.getLib libICE}" \
+            "${lib.getLib libSM}" \
+            "${lib.getLib libX11}"
+        '';
+      }
+    );
+
+  "SkiaSharp.NativeAssets.Linux" =
+    package:
+    package.overrideAttrs (
+      old:
+      lib.optionalAttrs stdenv.isLinux {
+        nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ autoPatchelfHook ];
+
+        buildInputs = old.buildInputs or [ ] ++ [ fontconfig ];
+
+        preInstall =
+          old.preInstall or ""
+          + ''
+            cd runtimes
+            for platform in *; do
+              [[ $platform == "${dotnetCorePackages.systemToDotnetRid stdenv.hostPlatform.system}" ]] ||
+                rm -r "$platform"
+            done
+            cd - >/dev/null
+          '';
+      }
+    );
+}
diff --git a/pkgs/build-support/dotnet/make-nuget-deps/default.nix b/pkgs/build-support/dotnet/make-nuget-deps/default.nix
index 341ab82ccddb..efc3d07e9777 100644
--- a/pkgs/build-support/dotnet/make-nuget-deps/default.nix
+++ b/pkgs/build-support/dotnet/make-nuget-deps/default.nix
@@ -5,6 +5,7 @@
 , unzip
 , patchNupkgs
 , nugetPackageHook
+, fetchNupkg
 }:
 lib.makeOverridable(
   { name
@@ -15,56 +16,7 @@ lib.makeOverridable(
   (symlinkJoin {
     name = "${name}-nuget-deps";
     paths = nugetDeps {
-      fetchNuGet =
-        { pname
-        , version
-        , sha256 ? ""
-        , hash ? ""
-        , url ? "https://www.nuget.org/api/v2/package/${pname}/${version}" }:
-        stdenvNoCC.mkDerivation rec {
-          inherit pname version;
-
-          src = fetchurl {
-            name = "${pname}.${version}.nupkg";
-            # There is no need to verify whether both sha256 and hash are
-            # valid here, because nuget-to-nix does not generate a deps.nix
-            # containing both.
-            inherit url sha256 hash version;
-          };
-
-          nativeBuildInputs = [
-            unzip
-            patchNupkgs
-            nugetPackageHook
-          ];
-
-          unpackPhase = ''
-            unzip -nq $src
-            chmod -R +rw .
-          '';
-
-          prePatch = ''
-            shopt -s nullglob
-            local dir
-            for dir in tools runtimes/*/native; do
-              [[ ! -d "$dir" ]] || chmod -R +x "$dir"
-            done
-            rm -rf .signature.p7s
-          '';
-
-          installPhase = ''
-            dir=$out/share/nuget/packages/${lib.toLower pname}/${lib.toLower version}
-            mkdir -p $dir
-            cp -r . $dir
-            echo {} > "$dir"/.nupkg.metadata
-          '';
-
-          preFixup = ''
-            patch-nupkgs $out/share/nuget/packages
-          '';
-
-          createInstallableNugetSource = installable;
-        };
+      fetchNuGet = args: fetchNupkg (args // { inherit installable; });
     };
   }) // {
     inherit sourceFile;
diff --git a/pkgs/by-name/be/beatsabermodmanager/package.nix b/pkgs/by-name/be/beatsabermodmanager/package.nix
index 96705c35d345..e11f60c39508 100644
--- a/pkgs/by-name/be/beatsabermodmanager/package.nix
+++ b/pkgs/by-name/be/beatsabermodmanager/package.nix
@@ -5,11 +5,6 @@
 
   dotnetCorePackages,
 
-  libX11,
-  libICE,
-  libSM,
-  fontconfig,
-
   xdg-utils,
 }:
 
@@ -38,12 +33,6 @@ buildDotnetModule rec {
 
   nugetDeps = ./deps.nix;
 
-  runtimeDeps = [
-    libX11
-    libICE
-    libSM
-    fontconfig
-  ];
 
   # Required for OneClick
   makeWrapperArgs = [
diff --git a/pkgs/by-name/bl/blendfarm/package.nix b/pkgs/by-name/bl/blendfarm/package.nix
index badbda23c38a..4eeabc18efaf 100644
--- a/pkgs/by-name/bl/blendfarm/package.nix
+++ b/pkgs/by-name/bl/blendfarm/package.nix
@@ -6,9 +6,6 @@
   dotnetCorePackages,
   xz,
   pcre,
-  libX11,
-  libICE,
-  libSM,
   autoPatchelfHook,
   bintools,
   fixDarwinDylibNames,
@@ -77,13 +74,9 @@ buildDotnetModule rec {
   runtimeDeps = [
     xz
     pcre
-    libX11
-    libICE
-    libSM
     libgdiplus
     glib
     libXrandr
-    fontconfig
   ] ++ lib.optionals stdenv.hostPlatform.isLinux [ blender ];
 
   # there is no "*.so.3" or "*.so.5" in nixpkgs. So ignore the warning
diff --git a/pkgs/by-name/kn/knossosnet/package.nix b/pkgs/by-name/kn/knossosnet/package.nix
index a6a41e20fc73..7abcb75f3c9a 100644
--- a/pkgs/by-name/kn/knossosnet/package.nix
+++ b/pkgs/by-name/kn/knossosnet/package.nix
@@ -1,10 +1,8 @@
 {
   buildDotnetModule
   , fetchFromGitHub
-  , fontconfig
   , lib
   , openal
-  , xorg
 }:
 
 buildDotnetModule rec {
@@ -23,7 +21,7 @@ buildDotnetModule rec {
   nugetDeps = ./deps.nix;
   executables = [ "Knossos.NET" ];
 
-  runtimeDeps = [ fontconfig openal xorg.libX11 xorg.libICE xorg.libSM ];
+  runtimeDeps = [ openal ];
 
   meta = with lib; {
     homepage = "https://github.com/KnossosNET/Knossos.NET";
diff --git a/pkgs/by-name/li/libation/package.nix b/pkgs/by-name/li/libation/package.nix
index fc61d7c0d48f..b84469c716fb 100644
--- a/pkgs/by-name/li/libation/package.nix
+++ b/pkgs/by-name/li/libation/package.nix
@@ -6,14 +6,6 @@
   dotnetCorePackages,
   wrapGAppsHook3,
 
-  libX11,
-  libICE,
-  libSM,
-  libXi,
-  libXcursor,
-  libXext,
-  libXrandr,
-  fontconfig,
   glew,
   gtk3,
 }:
@@ -48,14 +40,6 @@ buildDotnetModule rec {
 
   runtimeDeps = [
     # For Avalonia UI
-    libX11
-    libICE
-    libSM
-    libXi
-    libXcursor
-    libXext
-    libXrandr
-    fontconfig
     glew
     # For file dialogs
     gtk3
diff --git a/pkgs/by-name/lu/lumafly/package.nix b/pkgs/by-name/lu/lumafly/package.nix
index 14227990c490..c15e290b465c 100644
--- a/pkgs/by-name/lu/lumafly/package.nix
+++ b/pkgs/by-name/lu/lumafly/package.nix
@@ -5,11 +5,7 @@
   dotnetCorePackages,
   zlib,
   icu,
-  fontconfig,
   openssl,
-  libX11,
-  libICE,
-  libSM,
   icoutils,
   copyDesktopItems,
   makeDesktopItem,
@@ -36,11 +32,7 @@ buildDotnetModule rec {
   runtimeDeps = [
     zlib
     icu
-    fontconfig
     openssl
-    libX11
-    libICE
-    libSM
   ];
 
   nativeBuildInputs = [
diff --git a/pkgs/by-name/ne/nexusmods-app/package.nix b/pkgs/by-name/ne/nexusmods-app/package.nix
index 68f5dadc393a..6d07a5b93f9e 100644
--- a/pkgs/by-name/ne/nexusmods-app/package.nix
+++ b/pkgs/by-name/ne/nexusmods-app/package.nix
@@ -7,9 +7,6 @@
   fetchFromGitHub,
   fontconfig,
   lib,
-  libICE,
-  libSM,
-  libX11,
   runCommand,
   pname ? "nexusmods-app",
 }:
@@ -62,13 +59,6 @@ buildDotnetModule (finalAttrs: {
 
   runtimeInputs = [ desktop-file-utils ];
 
-  runtimeDeps = [
-    fontconfig
-    libICE
-    libSM
-    libX11
-  ];
-
   executables = [ "NexusMods.App" ];
 
   doCheck = true;
diff --git a/pkgs/by-name/re/retrospy/package.nix b/pkgs/by-name/re/retrospy/package.nix
index a68b08617f43..a207150e1e47 100644
--- a/pkgs/by-name/re/retrospy/package.nix
+++ b/pkgs/by-name/re/retrospy/package.nix
@@ -4,11 +4,6 @@
 , copyDesktopItems
 , makeDesktopItem
 , lib
-, fontconfig
-, libX11
-, libXcursor
-, libICE
-, libSM
 , runCommandLocal
 }:
 let
@@ -43,14 +38,6 @@ buildDotnetModule {
     copyDesktopItems
   ];
 
-  runtimeDeps = [
-    fontconfig
-    libX11
-    libICE
-    libXcursor
-    libSM
-  ];
-
   projectFile = [
     "RetroSpyX/RetroSpyX.csproj"
     "GBPemuX/GBPemuX.csproj"
diff --git a/pkgs/by-name/ro/roslyn-ls/deps.nix b/pkgs/by-name/ro/roslyn-ls/deps.nix
index 27aa7a75d268..a16363944efd 100644
--- a/pkgs/by-name/ro/roslyn-ls/deps.nix
+++ b/pkgs/by-name/ro/roslyn-ls/deps.nix
@@ -2,6 +2,7 @@
 # Please dont edit it manually, your changes might get overwritten!
 
 { fetchNuGet }: [
+  (fetchNuGet { pname = "dotnet-format"; version = "7.0.360304"; hash = "sha256-TuhZIhearocl702hLzGJCcRd8+RWoI4tDY02Bf6Lus8="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/d1622942-d16f-48e5-bc83-96f4539e7601/nuget/v3/flat2/dotnet-format/7.0.360304/dotnet-format.7.0.360304.nupkg"; })
   (fetchNuGet { pname = "Humanizer.Core"; version = "2.14.1"; hash = "sha256-EXvojddPu+9JKgOG9NSQgUTfWq1RpOYw7adxDPKDJ6o="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/humanizer.core/2.14.1/humanizer.core.2.14.1.nupkg"; })
   (fetchNuGet { pname = "ICSharpCode.Decompiler"; version = "8.1.1.7464"; hash = "sha256-71/e9zuQIfqRXOiWxZkUFW/tMAj63nE8tg/sR7bGzuM="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/icsharpcode.decompiler/8.1.1.7464/icsharpcode.decompiler.8.1.1.7464.nupkg"; })
   (fetchNuGet { pname = "MessagePack"; version = "2.5.108"; hash = "sha256-+vMXyEbfutY5WOFuFnNF24uLcKJTTdntVrVlSJH4yjI="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/messagepack/2.5.108/messagepack.2.5.108.nupkg"; })
@@ -116,6 +117,7 @@
   (fetchNuGet { pname = "NuGet.ProjectModel"; version = "6.8.0-rc.112"; hash = "sha256-geQh1fSRTp2FTzeilFL8gxFFq7q8u7YaakShPKiTwns="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/d1622942-d16f-48e5-bc83-96f4539e7601/nuget/v3/flat2/nuget.projectmodel/6.8.0-rc.112/nuget.projectmodel.6.8.0-rc.112.nupkg"; })
   (fetchNuGet { pname = "NuGet.Protocol"; version = "6.8.0-rc.112"; hash = "sha256-6r/MJCo2ngibSAfNdH+xmeNUl38EPjQkaewKsTJpfvU="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/d1622942-d16f-48e5-bc83-96f4539e7601/nuget/v3/flat2/nuget.protocol/6.8.0-rc.112/nuget.protocol.6.8.0-rc.112.nupkg"; })
   (fetchNuGet { pname = "NuGet.Versioning"; version = "6.8.0-rc.112"; hash = "sha256-BzAWS5wpGnNj0gU33sfWao7BELGjrQBT4xj3EC7qRRE="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/d1622942-d16f-48e5-bc83-96f4539e7601/nuget/v3/flat2/nuget.versioning/6.8.0-rc.112/nuget.versioning.6.8.0-rc.112.nupkg"; })
+  (fetchNuGet { pname = "PowerShell"; version = "7.0.0"; hash = "sha256-ioasr71UIhDmeZ2Etw52lQ7QsioEd1pnbpVlEeCyUI4="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/powershell/7.0.0/powershell.7.0.0.nupkg"; })
   (fetchNuGet { pname = "RichCodeNav.EnvVarDump"; version = "0.1.1643-alpha"; hash = "sha256-bwND+Na9iEnkEdeL1elY34+m4/F4BYATBHv/2BEw4d4="; url = "https://pkgs.dev.azure.com/azure-public/3ccf6661-f8ce-4e8a-bb2e-eff943ddd3c7/_packaging/58ca65bb-e6c1-4210-88ac-fa55c1cd7877/nuget/v3/flat2/richcodenav.envvardump/0.1.1643-alpha/richcodenav.envvardump.0.1.1643-alpha.nupkg"; })
   (fetchNuGet { pname = "Roslyn.Diagnostics.Analyzers"; version = "3.11.0-beta1.24081.1"; hash = "sha256-wIOhKwvYetwytnuNX0uNC5oyBDU7xAhLqzTvyuGDVMM="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/a54510f9-4b2c-4e69-b96a-6096683aaa1f/nuget/v3/flat2/roslyn.diagnostics.analyzers/3.11.0-beta1.24081.1/roslyn.diagnostics.analyzers.3.11.0-beta1.24081.1.nupkg"; })
   (fetchNuGet { pname = "runtime.any.System.Collections"; version = "4.3.0"; hash = "sha256-4PGZqyWhZ6/HCTF2KddDsbmTTjxs2oW79YfkberDZS8="; url = "https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/runtime.any.system.collections/4.3.0/runtime.any.system.collections.4.3.0.nupkg"; })
diff --git a/pkgs/by-name/ro/roslyn-ls/package.nix b/pkgs/by-name/ro/roslyn-ls/package.nix
index 3207eea29d09..8955d46b5b7b 100644
--- a/pkgs/by-name/ro/roslyn-ls/package.nix
+++ b/pkgs/by-name/ro/roslyn-ls/package.nix
@@ -33,7 +33,7 @@ buildDotnetModule rec {
     jq '.sdk.rollForward = "latestMinor"' < global.json > global.json.tmp
     mv global.json.tmp global.json
 
-    substituteInPlace $projectFile \
+    substituteInPlace $dotnetProjectFiles \
       --replace-fail \
         '>win-x64;win-arm64;linux-x64;linux-arm64;linux-musl-x64;linux-musl-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>' \
         '>linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>'
@@ -58,7 +58,7 @@ buildDotnetModule rec {
     ''
       runHook preInstall
 
-      env dotnet publish $projectFile \
+      env dotnet publish $dotnetProjectFiles \
           -p:ContinuousIntegrationBuild=true \
           -p:Deterministic=true \
           -p:InformationalVersion=$version \
diff --git a/pkgs/by-name/ry/ryujinx/package.nix b/pkgs/by-name/ry/ryujinx/package.nix
index 590b7cfc7cce..5ff91a281cd4 100644
--- a/pkgs/by-name/ry/ryujinx/package.nix
+++ b/pkgs/by-name/ry/ryujinx/package.nix
@@ -10,13 +10,6 @@
 , sndio
 , pulseaudio
 , vulkan-loader
-, libICE
-, libSM
-, libXi
-, libXcursor
-, libXext
-, libXrandr
-, fontconfig
 , glew
 , libGL
 , udev
@@ -55,13 +48,6 @@ buildDotnetModule rec {
     udev
 
     # Avalonia UI
-    libICE
-    libSM
-    libXi
-    libXcursor
-    libXext
-    libXrandr
-    fontconfig
     glew
 
     # Headless executable
diff --git a/pkgs/development/compilers/dotnet/default.nix b/pkgs/development/compilers/dotnet/default.nix
index 9a1acf4ad70d..1a2fdc7f8dd1 100644
--- a/pkgs/development/compilers/dotnet/default.nix
+++ b/pkgs/development/compilers/dotnet/default.nix
@@ -51,6 +51,13 @@ makeScopeWithSplicing' {
       patchNupkgs = callPackage ./patch-nupkgs.nix {};
       nugetPackageHook = callPackage ./nuget-package-hook.nix {};
 
+      buildDotnetModule = callPackage ../../../build-support/dotnet/build-dotnet-module { };
+      buildDotnetGlobalTool = callPackage ../../../build-support/dotnet/build-dotnet-global-tool { };
+
+      mkNugetSource = callPackage ../../../build-support/dotnet/make-nuget-source { };
+      mkNugetDeps = callPackage ../../../build-support/dotnet/make-nuget-deps { };
+      fetchNupkg = callPackage ../../../build-support/dotnet/fetch-nupkg { };
+
       dotnet_8 = recurseIntoAttrs (callPackage ./8 { bootstrapSdk = dotnet_8_0.sdk_8_0_1xx; });
       dotnet_9 = recurseIntoAttrs (callPackage ./9 {});
     } // lib.optionalAttrs config.allowAliases {
diff --git a/pkgs/development/compilers/dotnet/dotnet-sdk-setup-hook.sh b/pkgs/development/compilers/dotnet/dotnet-sdk-setup-hook.sh
index cac55cb56017..fccf6b02aaeb 100644
--- a/pkgs/development/compilers/dotnet/dotnet-sdk-setup-hook.sh
+++ b/pkgs/development/compilers/dotnet/dotnet-sdk-setup-hook.sh
@@ -16,6 +16,7 @@ _linkPackages() {
     local -r src="$1"
     local -r dest="$2"
     local dir
+    local x
 
     for x in "$src"/*/*; do
         dir=$dest/$(basename "$(dirname "$x")")
@@ -27,8 +28,9 @@ _linkPackages() {
 createNugetDirs() {
     nugetTemp=$PWD/.nuget-temp
     export NUGET_PACKAGES=$nugetTemp/packages
+    export NUGET_FALLBACK_PACKAGES=$nugetTemp/fallback
     nugetSource=$nugetTemp/source
-    mkdir -p "$NUGET_PACKAGES" "$nugetSource"
+    mkdir -p "$NUGET_PACKAGES" "$NUGET_FALLBACK_PACKAGES" "$nugetSource"
 
     dotnet new nugetconfig
     if [[ -z ${keepNugetConfig-} ]]; then
@@ -39,9 +41,11 @@ createNugetDirs() {
 }
 
 configureNuget() {
+    local x
+
     for x in "${!_nugetInputs[@]}"; do
         if [[ -d $x/share/nuget/packages ]]; then
-            addToSearchPathWithCustomDelimiter ";" NUGET_FALLBACK_PACKAGES "$x/share/nuget/packages"
+            _linkPackages "$x/share/nuget/packages" "$NUGET_FALLBACK_PACKAGES"
         fi
 
         if [[ -d $x/share/nuget/source ]]; then
@@ -60,7 +64,7 @@ configureNuget() {
         done
     fi
 
-    if [[ -f paket.dependencies ]]; then
+    if [[ -z ${keepNugetConfig-} && -f paket.dependencies ]]; then
        sed -i "s:source .*:source $nugetSource:" paket.dependencies
        sed -i "s:remote\:.*:remote\: $nugetSource:" paket.lock
 
diff --git a/pkgs/development/compilers/dotnet/packages.nix b/pkgs/development/compilers/dotnet/packages.nix
index db9b5e68bdbf..fc569b6b7e1f 100644
--- a/pkgs/development/compilers/dotnet/packages.nix
+++ b/pkgs/development/compilers/dotnet/packages.nix
@@ -65,6 +65,7 @@ in {
             read version
             mkdir -p "$packages"/share/nuget/packages/"$id"
             cp -r "$package" "$packages"/share/nuget/packages/"$id"/"$version"
+            echo {} > "$packages"/share/nuget/packages/"$id"/"$version"/.nupkg.metadata
           )
         fi
       done
diff --git a/pkgs/development/python-modules/clr-loader/default.nix b/pkgs/development/python-modules/clr-loader/default.nix
index 6b3d2c3faa39..583cf34320e4 100644
--- a/pkgs/development/python-modules/clr-loader/default.nix
+++ b/pkgs/development/python-modules/clr-loader/default.nix
@@ -38,8 +38,7 @@ buildPythonPackage {
 
   buildInputs = [
     dotnetCorePackages.sdk_6_0.packages
-    dotnet-build.nugetDeps
-  ];
+  ] ++ dotnet-build.nugetDeps;
 
   nativeBuildInputs = [
     setuptools
diff --git a/pkgs/development/python-modules/pythonnet/default.nix b/pkgs/development/python-modules/pythonnet/default.nix
index 969534e80cef..9119f1a27268 100644
--- a/pkgs/development/python-modules/pythonnet/default.nix
+++ b/pkgs/development/python-modules/pythonnet/default.nix
@@ -37,7 +37,7 @@ buildPythonPackage {
       --replace 'dynamic = ["version"]' 'version = "${version}"'
   '';
 
-  buildInputs = [ dotnet-build.nugetDeps ];
+  buildInputs = dotnet-build.nugetDeps;
 
   nativeBuildInputs = [
     setuptools
diff --git a/pkgs/games/space-station-14-launcher/space-station-14-launcher.nix b/pkgs/games/space-station-14-launcher/space-station-14-launcher.nix
index cde4cee0384a..10dfea3d7dee 100644
--- a/pkgs/games/space-station-14-launcher/space-station-14-launcher.nix
+++ b/pkgs/games/space-station-14-launcher/space-station-14-launcher.nix
@@ -6,14 +6,6 @@
 , iconConvTools
 , copyDesktopItems
 , makeDesktopItem
-, libX11
-, libICE
-, libSM
-, libXi
-, libXcursor
-, libXext
-, libXrandr
-, fontconfig
 , glew
 , SDL2
 , glfw
@@ -95,14 +87,6 @@ buildDotnetModule rec {
     gdk-pixbuf
 
     # Avalonia UI dependencies.
-    libX11
-    libICE
-    libSM
-    libXi
-    libXcursor
-    libXext
-    libXrandr
-    fontconfig
     glew
   ];
 
diff --git a/pkgs/test/dotnet/default.nix b/pkgs/test/dotnet/default.nix
index 72c2f5a64def..601cf5c15e4e 100644
--- a/pkgs/test/dotnet/default.nix
+++ b/pkgs/test/dotnet/default.nix
@@ -5,4 +5,5 @@
   use-dotnet-from-env = lib.recurseIntoAttrs (callPackage ./use-dotnet-from-env { });
   structured-attrs = lib.recurseIntoAttrs (callPackage ./structured-attrs { });
   final-attrs = lib.recurseIntoAttrs (callPackage ./final-attrs { });
+  nuget-deps = lib.recurseIntoAttrs (callPackage ./nuget-deps { });
 }
diff --git a/pkgs/test/dotnet/nuget-deps/default.nix b/pkgs/test/dotnet/nuget-deps/default.nix
new file mode 100644
index 000000000000..bf0e1445e93e
--- /dev/null
+++ b/pkgs/test/dotnet/nuget-deps/default.nix
@@ -0,0 +1,44 @@
+# Tests that `nugetDeps` in buildDotnetModule can handle various types.
+
+{
+  lib,
+  dotnet-sdk,
+  buildPackages, # buildDotnetModule
+  runCommand,
+}:
+
+let
+  inherit (lib)
+    mapAttrs
+    ;
+
+  inherit (buildPackages)
+    emptyDirectory
+    buildDotnetModule
+    ;
+
+in
+mapAttrs
+  (
+    name: nugetDeps:
+    buildDotnetModule {
+      name = "nuget-deps-${name}";
+      unpackPhase = ''
+        runHook preUnpack
+
+        mkdir test
+        cd test
+        dotnet new console -o .
+        ls -l
+
+        runHook postUnpack
+      '';
+      inherit nugetDeps;
+    }
+  )
+  {
+    "null" = null;
+    "file" = ./nuget-deps.nix;
+    "derivation" = emptyDirectory;
+    "list" = [ emptyDirectory ];
+  }
diff --git a/pkgs/test/dotnet/nuget-deps/nuget-deps.nix b/pkgs/test/dotnet/nuget-deps/nuget-deps.nix
new file mode 100644
index 000000000000..dbfecc1b2605
--- /dev/null
+++ b/pkgs/test/dotnet/nuget-deps/nuget-deps.nix
@@ -0,0 +1,6 @@
+# This file was automatically generated by passthru.fetch-deps.
+# Please dont edit it manually, your changes might get overwritten!
+
+{ fetchNuGet }:
+[
+]
diff --git a/pkgs/tools/games/scarab/default.nix b/pkgs/tools/games/scarab/default.nix
index 11ec9e7cdd02..02dec25949e0 100644
--- a/pkgs/tools/games/scarab/default.nix
+++ b/pkgs/tools/games/scarab/default.nix
@@ -3,10 +3,6 @@
 , fetchFromGitHub
 , glibc
 , zlib
-, libX11
-, libICE
-, libSM
-, fontconfig
 , gtk3
 , copyDesktopItems
 , icoutils
@@ -32,10 +28,6 @@ buildDotnetModule rec {
   runtimeDeps = [
     glibc
     zlib
-    libX11
-    libICE
-    libSM
-    fontconfig
     gtk3
   ];
 
diff --git a/pkgs/tools/networking/mqttmultimeter/default.nix b/pkgs/tools/networking/mqttmultimeter/default.nix
index 1c2c290bef78..29990cbc83a8 100644
--- a/pkgs/tools/networking/mqttmultimeter/default.nix
+++ b/pkgs/tools/networking/mqttmultimeter/default.nix
@@ -4,8 +4,6 @@
 , dotnet-runtime_8
 , buildDotnetModule
 , fetchFromGitHub
-, fontconfig
-, xorg
 , libglvnd
 , makeDesktopItem
 , copyDesktopItems
@@ -34,7 +32,7 @@ buildDotnetModule rec {
     copyDesktopItems
   ];
 
-  buildInputs = [ stdenv.cc.cc.lib fontconfig ];
+  buildInputs = [ stdenv.cc.cc.lib ];
 
   postInstall = ''
     rm -rf $out/lib/${lib.toLower pname}/runtimes/{*musl*,win*}
@@ -42,9 +40,6 @@ buildDotnetModule rec {
 
   runtimeDeps = [
     libglvnd
-    xorg.libSM
-    xorg.libICE
-    xorg.libX11
   ];
 
   desktopItems = makeDesktopItem {
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 2b5eb6ace435..fe1c54db299a 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -875,12 +875,8 @@ with pkgs;
   dotnet-runtime = dotnetCorePackages.runtime_6_0;
   dotnet-aspnetcore = dotnetCorePackages.aspnetcore_6_0;
 
-  buildDotnetModule = callPackage ../build-support/dotnet/build-dotnet-module { };
   nuget-to-nix = callPackage ../build-support/dotnet/nuget-to-nix { };
-  mkNugetSource = callPackage ../build-support/dotnet/make-nuget-source { };
-  mkNugetDeps = (newScope dotnetCorePackages) ../build-support/dotnet/make-nuget-deps { };
-
-  buildDotnetGlobalTool = callPackage ../build-support/dotnet/build-dotnet-global-tool { };
+  inherit (dotnetCorePackages) buildDotnetModule buildDotnetGlobalTool mkNugetSource mkNugetDeps;
 
   fsautocomplete = callPackage ../development/tools/fsautocomplete { };