How to install Spyder

Disclaimer:

  1. I don’t know if it is proper or not. But it should work.
  2. I’m not an expert, improvement is welcome! I hope if it’s good enough, it will be on the wiki.
  3. This guide uses Spyder 6.1.2 with Qt6 webengine support (currently in unstable).
  4. Don’t use older Spyder with Qt5 webengine version. Since it contains lot CVE’s and not in nix cache so you need to built it yourself.
  5. I use NixOS with home-manager, flake and direnv. But you should able to adapt this to your configuration.

Install Spyder:

We must put Spyder and its dependecies inside single python closure so Spyder can detect the dependencies. If you set the Spyder python interpreter with internal path, you can use Spyder everywhere as long the python package in your code is also installed in that python clouse.

packages = with pkgs-unstable; [
  (python3.withPackages (python-pkgs: with python-pkgs;[
    spyder
    spyder-kernels
    pandas # optional
  ]))
];

You can install bare Spyder like below, but you must install spyder-kernels package in your python environment and set that Spyder’s python interpreter path to that environment. In this mode, even if your environment has pandas, it won’t be detected by Spyder GUI so no dataframe visualization. The code will still work.

packages = with pkgs-unstable; [
  spyder
];

For example, I use this flake with direnv for my python environment. Would be better if you learn direnv first. The important part is the $LD_LIBRARY_PATH export. Spyder must be called from the direnv console with that $LD_LIBRARY_PATH environment variable. To install the direnv environment we call $ nix develop .#setupShell which also install spyder-kernels in the python virtual environment.

  description = "test";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";

    flake-utils.url = "github:numtide/flake-utils";
  };
  outputs = {
    nixpkgs,
    flake-utils,
    ...
  }:
    flake-utils.lib.eachDefaultSystem (system: let
      pkgs = nixpkgs.legacyPackages.${system};
      buildInputs = [
        (pkgs.python3.withPackages (python-pkgs: [
          python-pkgs.pip
          python-pkgs.virtualenv
        ]))
      ];
    in {
      devShells.default = pkgs.mkShell {
        inherit buildInputs;
        shellHook = ''
          export LD_LIBRARY_PATH=${pkgs.stdenv.cc.cc.lib}/lib/
          export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH"
          source .venv/bin/activate
        '';
      };
      devShells.setupShell = pkgs.mkShell {
        inherit buildInputs;
        shellHook = ''
          export LD_LIBRARY_PATH=${pkgs.stdenv.cc.cc.lib}/lib/
          rm -rf .venv
          virtualenv --no-setuptools .venv
          source .venv/bin/activate
          pip install spyder-kernels==3.1
        '';
      };
    });
}

Additional Tips:
If you want to use Qt matplotlib backend with Wayland from Spyder than launched from desktop start menu, You need to put some library path in LD_LIBRARY_PATH like this in you home-manager:

  home.sessionVariables = {
      LD_LIBRARY_PATH = let
        libs = with pkgs; [
          # For matplotlib qt backend in spyder
          stdenv.cc.cc.lib
          glib
          zlib
          zstd
          libGL
          fontconfig
          libxkbcommon
          freetype
          dbus
          xorg.libX11
          wayland
        ];
      in lib.makeLibraryPath libs;
    };

Relevant Reference:

  1. Missing username in spyder PATH when launched from desktop
1 Like

Thanks for your examples. I took a different approach without relying on PATH magic and it seems to work alright (haven’t done any testing with funny libraries yet):

# This opens Spyder with its own runtime dependencies plus the given packages available
nix run git+https://codeberg.org/nobodyinperson/nix-spyder#withPackages numpy scipy matplotlib

This is a basic flake template that you can adjust locally and nix run yourself:

{
  description = "Spyder";
  inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; };
  outputs = { self, nixpkgs }:
    let inherit (nixpkgs) lib;
    in {
      lib.mkPythonEnv = python: packagesSelector:
        python.withPackages (ps:
          (with ps; [
            # required for spyder
            spyder
            spyder-kernels
            ipython
            python-lsp-server
          ]) ++ (packagesSelector ps));
      apps = lib.genAttrs lib.systems.flakeExposed (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
          pythonEnv = self.lib.mkPythonEnv pkgs.python3 (ps:
            with ps; [
              # extra packages
              matplotlib
              pandas
              numpy
              scipy
            ]);
        in {
          default = {
            type = "app";
            meta.description =
              "Spyder Python IDE with certain packages installed";
            program = "${pythonEnv}/bin/spyder";
          };
        });
    };
}

Very nice. Using your method which doesn’t use PATH magic, I hope I can run global spyder with arbitrary python environment without getting ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory

EDIT:
Well I still got that error, but because of that I remember this tool fix-python

Yeah my solution doesn’t solve that, it’s only for a fixed set of nixpkgs Python packages.