/nix-system-graphics

Run graphics accelerated programs built with Nix on any Linux distribution.

Primary LanguageNixMIT LicenseMIT

Nix System Graphics

Run graphics accelerated programs built with Nix on any Linux distribution. Works with both OpenGL and Vulkan seamlessly.

Table of contents

Comparison Table

NixGL nix-gl-host nix-system-graphics
Requires no wrapping? (no nixgl ...)
Works with AMD/Intel? (Mesa)
Works with Nvidia? (Proprietary)
Works with nix run nixpkgs#...? ⚠️¹ ⚠️¹
Nix program can launch system apps? ² ²
Is it Open Source? ³ ✅ (Apache-2.0) ✅ (MIT)
  1. Requires wrapping nix run with their wrapper before it works.
  2. Can be done in very select cases under certain setups by manually changing internal variables. Example.
  3. NixGL is proprietary as it has no license information. See this Github issue for more information.

Installing with Nix Flakes

Ensure you have Nix installed with Flakes support enabled. If you do not have Nix installed already, you can do this by installing Lix or using one of the nix-installers which enable this automatically. Alternatively, you may also enable Flakes support manually if you have installed Nix with another approach, but didn't enable Flakes support for you.

Now, adding a system-manager config will be very individualized to how your flake.nix is written, but generally a complete file would look like the following.

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    system-manager = {
      url = "github:numtide/system-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    nix-system-graphics = {
      url = "github:soupglasses/nix-system-graphics";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, flake-utils, nixpkgs, system-manager, nix-system-graphics }: {
    systemConfigs.default = system-manager.lib.makeSystemConfig {
      modules = [
        nix-system-graphics.systemModules.default
        ({
          config = {
            nixpkgs.hostPlatform = "x86_64-linux";
            system-manager.allowAnyDistro = true;
            system-graphics.enable = true;
          };
        })
      ];
    };
  };
}

Then you can change into your system-manager config by using the system-manager package, either by installing it, running it in a development shell, or running it directly from the upstream flake URL, which we will do here.

nix run 'github:numtide/system-manager' -- switch --flake '.'

Lastly, to verify that the driver is now functioning on your system, you may run the following command.

nix shell 'nixpkgs#mesa-demos' --command glxgears

Extra Graphical Packages

Important

This section is currently under testing and may not work as expected, so if you hit any issues or simply have success with this method, please give feedback in the following Github issue #4.

You should be able to add VA-API/VDPAU/OpenCL/CUDA support similarly as you would in NixOS. Just add the relevant packages to system-graphics.extraPackages and system-graphics.extraPackages32 as needed. Due to the variety of libraries that could possibly be added here, I recommend to read up on the relevant NixOS Wiki pages.

Accelerated Video Playback | AMD OpenCL | Nvidia CUDA

Nvidia Support

Important

This section is currently under testing and may not work as expected, so if you hit any issues or simply have success with this method, please give feedback in the following Github issue #5.

For a machine running the proprietary nvidia driver, the default mesa drivers will not work. So instead, please add the following to the config section of the system-manager config.

system-graphics.package = pkgs.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; };
# Only required if you enable `system-graphics.enable32Bit`
system-graphics.package32 = (pkgs.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; }).lib32;

There exists multiple versions of the NVIDIA driver, and they are typically incompatible with one another. So pay extra attention on pinning the NVIDIA driver to the correct major version. You should be able to see the current NVIDA driver version you have by running the command cat /proc/driver/nvidia/version.

If you still have issues, you can try to pin your driver to the spessific version you are using manually, filling out the sha256 sums with lib.fakeSha256 and removing them as you rebuild. This step however should generally not be needed, and the major version should be enough.

But why another Nix-with-OpenGL project?

While there are existing solutions like nixGL and nix-gl-host, they share a significant drawback: they rely on wrapping the execution of a Nix-built binary with internal environment variables, such as LIBGL_DRIVER_PATH and __EGL_VENDOR_LIBRARY_FILENAMES. You can find the full list of these variables as used by nixGL here.

While this method works, it introduces a key limitation. If your application running via nixGL calls another application, that second application also needs to support nixGL’s specific versions of those graphics libraries, as these get propagated down through the environment variables. In simpler terms, system-installed applications tend to crash or behave unpredictably, as seen in this issue. You could try unsetting these environment variables on a per-application basis after launching, but this process is both error-prone and time-consuming.

Now, in contrast, nix-system-graphics addresses this issue by populating /run/opengl-driver in the same way NixOS handles it. This eliminates the need to patch or wrap applications built from the Nix store, as they are already configured to use the /run/opengl-driver path by default for their libGL and libvulkan needs. Since there’s no need to wrap any binaries anymore, all system applications work will work flawlessly, even when launched through a Nix-packaged application. As a result, using Nix-packaged window managers like i3 or sway, or a graphically accelerated terminal emulator like alacritty, becomes a smooth and hassle-free experience, even when calling graphically accelerated system applications.

Acknowledgements

Special thanks goes out to @picnoir who created nix-gl-host, who also so kindly helped me with reflecting on the feasabilitiy of this project.