Having all python packages in default env, HOW?

Pretty straight forward:
Im on nixos with flakes and home-manager. I used to have a packages.nix file for all environment.systemPackages and a home.nix file for all home.packages entries.

So my home looks a bit like this snippet below, my issue is that when i do python -c "import pandas; print(pandas.__file__)" i get:

Traceback (most recent call last):
File “”, line 1, in
ModuleNotFoundError: No module named ‘pandas’


  home = {
    stateVersion = "25.05";


    username = username;
    homeDirectory = "/home/${username}";

    # User-specific packages
    packages = with pkgs;
      cmake
      fd
      alejandra
      pre-commit
      nodejs
      [and more ...]
      (python312.withPackages (
        ps:
          with ps; [
            pyquery
            imbalanced-learn
            scipy
            requests # A standard python library
            rich
            polars
            matplotlib
            pillow
            opencv4
            plotly
            pytest
            seaborn
            python-dotenv
            regex
            # tabulate
            ipykernel
            aiofiles
            pip
            scikit-learn
            debugpy
            numpy
            pandas
            sqlalchemy
          ]
      ))
    ];

so everytime i rebuild the system i need to go to /nix/store and search which folder has that new package, and then set that paths bin folder as the path to the interpreter, very annoying

how can i make sure that ALL python packages/modules are just available by the default python env which is always softlinked at /etc/profiles/per-user/username/bin/python ???

1 Like

Can’t repro. If I take a minimal reproducer

❯ eval "$(nix-build --no-out-link -E '(import <nixpkgs> {}).python3.withPackages(p: [p.pandas])')/bin/python -c 'import pandas; print(pandas.__file__)'"
/nix/store/97njs47mk3plrkaz95bng2yp3q5k232y-python3-3.12.11-env/lib/python3.12/site-packages/pandas/__init__.py

it works just fine. It also works from a shell, and also works from home.packages, so there is something more complicated going on. Might be worth trying to bisect that list of python packages?

This is not how development is intended to be done in Nix, and by proxy NixOS. You are supposed to create localized development shells via pkgs.mkShell that link the python modules you need in that local environment. Installing any kind of development software globally will 99% of the time fail because NixOS does not propagate the correct linking or configuration needed to make those tools work, only pkgs.mkShell does (in combination with nix-shell or nix develop).

3 Likes

I would like to suggest that OP probably isn’t trying to build software at all.

I have a very similar list of Python packages in my laptop’s configuration.nix, and a somewhat shorter list of R packages. This is because I use the ipython and R interactive environments as ridiculously overpowered desk calculators. Sometimes the stuff I type into the prompt gets turned into scripts down the road, but most of the time it’s, like, read in this specific CSV file, do some statistics, make a plot or two. One-off calculations, almost never revisited. It does not make sense to do this in a “localized development shell;” having to write a shell.nix at all is too much friction.

I do agree that this is not how Nix wants you to do things. Nix is very goal-oriented, and the goal is hermetic reproducible builds of packaged software. Any other use case is a second-class citizen, and at times it feels like that extends to any use of NixOS that isn’t “build farm.” That’s a bad thing. What OP wants is, IMO, a totally normal thing for someone to want on their personal workstation. NixOS ought to facilitate it somehow, and “write a shell.nix every time you need your desk calculator” ain’t it.

4 Likes

I think this is a valid use of global python. I use scala for that all the time through force of habit (and install it globally). I should probably get back to my roots and install R, it would make a lot more sense lol.

I also don’t understand why python3.withPackages(p: [p.pandas]) should be expected to fail to function. It just installs a python interpreter patched up with a site-packages that points a specific site packages directory that was built for it. Why shouldn’t this interpreter find and use pandas just fine? And if that’s true, seems like adding it to PATH doesn’t mystically cause it to cease to function.

It’ll work. But the question they asked is how to make every single python package (in some set) available without them having to add them into the list one-by-one.

@batou069 that’s basically impossible since some modules will inevitably conflict with each other. You’ll have to add them manually, unless you write some wrapper script that catches import errors, possibly providing a list of modules to pick from if there are multiple results, edits your configuration, and rebuilds your system.

First thanks for all the replies!

I am using nixos on my laptop which i use for my data-science/AI/ML course so i do coding on vscode (a little bit of nvim). Mostly python and jupiter notebooks.

When I start a new project then i don’t want to install new instances of the same modules (for example numpy, pandas, pytorch, …) for every project im working on, also I remember how big a .venv folder can get and i dont see why i need a new interpreter + modules for every new project.

I frankly don’t understand why (at least on my setup/config) when I add some python312 package to the python312.withPackages-list then the following happens:

  1. the default interpreter (the output of which python) constantly changes, which i expect due to the nature of nix and the hashing defining the folder name
  2. i need to go to /nix/store and find a file named by the module (for example opencv) and lookup that is in a folder that ends with the string python3-3.12.11-env, so i know what path to enter in vscode for the interpreter.

just opening ipython and importing any module won’t work, or choosing the “global” or “recommended” interpreter in vscode mostly won’t work, it’s either luck or looking it up (e.g., fd numpy /nix/store | grep python3-3.12.11-env)

Another important point to mention:
I tried troubleshooting it in many different ways but nothing worked:

  • moved the python312.withPackages ( ps: with ps; [ module1 module2 .... ]] from home.nix to packages.nix to turn it from user-wide to system-wide
  • moved the python312.withPackages part to config.nix to be with the overlays
  • Removed/disabeld anthing that might come with its own python version (xonsh, pyprland)

I am honeslty puzzled how to progress from here

This should not be happening, please share the rest of your config and explain precisely how you invoke python.

It sounds like you may be doing something bespoke with vscode, perhaps without realizing it.

If you just type python in a shell and try to import from there, you should in fact be getting your interpreter with pandas correctly installed. Hooking this up to some vscode plugin is an unrelated story and may in fact take a bit more effort since not every plugin author assumes you’re using nix.

This is expected, yes.

You should be able to get the right path by running this command in a shell window

type -p python3

Also try this command

python3 -c 'import sys; print(sys.executable)'

(They should print the same thing. If they don’t, please post the output of both commands in a follow-up message.)

(Footnote: never, ever refer to the Python 3 interpreter as just “python”; always use “python3”. This is less of a potential problem with NixOS than in some other environments but I still regularly trip over situations where bare python is Python 2.)

Now, I don’t use VSCode myself, but I would think that it ought to be able to do (effectively) the same thing as one of the above commands for itself, and not require you to configure it at all. What does VSCode say it’s trying to use when you set it to use either the “global” or “recommended” Python?

I honestly don’t know what change made it work, but i guess it works for now…
so the imports with default python work, but the paths displayed by both commands are different:

 lf @ ~ ❄️ ❯ type -p python3
python3 is /etc/profiles/per-user/lf/bin/python3

 lf @ ~ ❄️ ❯ python3 -c 'import sys; print(sys.executable)'
/nix/store/2xw8c9sqqr7762n34641zgzmilriligg-python3-3.12.11-env/bin/python3.12

 lf @ ~ ❄️ ❯ readlink -f $(which python3)
/nix/store/2xw8c9sqqr7762n34641zgzmilriligg-python3-3.12.11-env/bin/python3

 lf @ ~ ❄️ ❯ python3
Python 3.12.11 (main, Jun  3 2025, 15:41:47) [GCC 14.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> import pandas
>>>

VScode shows two other paths as global and another one non-global without any tag, both folders in /nix/store/…

my last changes were:

  1. moving the python stuff from packages.nix to home.nix
  2. disabling anything that might come with its own python environment: jupyter, pyprland, xonsh, …
  3. creating a shell.nix file in one of my coding projects that actually made “everything work”…

since i entered the shell of that shell.nix file and launched vscode from it it, everything just worked…no idea what exactly made it work or if it will keep working…

Not sure how relevant that is, but here are the shell.nix file and some relevant config files
Also any comment or suggestion to my config files is welcome, im a nix noob and AI can mess up quiet a bit

My shell.nix (not part of my nix config)

{pkgs ? import <nixpkgs> {}}: let
  python-with-packages = pkgs.python312.withPackages (ps:
    with ps; [
      numpy
      matplotlib
      scikit-learn
      torch
      pip
      
      (pkgs.python312Packages.opencv4.override {
        enableGtk2 = true; 
      })
    ]);
in

  pkgs.mkShell {
    buildInputs = [
      python-with-packages
      pkgs.pkg-config 
    ];
  }

my flake.nix

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
    home-manager = {
      url = "github:nix-community/home-manager/release-25.05";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-your-shell = {
      url = "github:MercuryTechnologies/nix-your-shell";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    stylix.url = "github:nix-community/stylix/release-25.05";
    ags = {
      url = "github:aylur/ags/v1";
      # url = "github:aylur/ags";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    firefox-addons = {
      url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-mineral = {
      url = "github:cynicsketch/nix-mineral";
      flake = false;
    };
    disko.url = "github:nix-community/disko";
    treefmt-nix.url = "github:numtide/treefmt-nix";
    sops-nix.url = "github:Mic92/sops-nix";
    flake-utils.url = "github:numtide/flake-utils";
    nur = {
      url = "github:nix-community/NUR";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    claudia = {
      url = "github:getAsterisk/claudia/218ecfb8b2069b69e4c40734e178e2a6af9fced7";
    };
    hyprland.url = "github:hyprwm/Hyprland";
    hyprland-plugins = {
      url = "github:hyprwm/hyprland-plugins";
      inputs.hyprland.follows = "hyprland";
    };
    hypr-dynamic-cursors = {
      url = "github:VirtCode/hypr-dynamic-cursors";
      inputs.hyprland.follows = "hyprland"; # to make sure that the plugin is built for the correct version of hyprland
    };
    pyprland.url = "github:hyprland-community/pyprland";
    mcp-servers-nix.url = "github:natsukium/mcp-servers-nix";
    # hyprpanel = {
    #   url = "github:Jas-SinghFSU/HyprPanel";
    #   inputs.nixpkgs.follows = "nixpkgs";
    # };
    nixvim = {
      url = "github:nix-community/nixvim";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
    flake-parts.url = "github:hercules-ci/flake-parts";
    zen-browser = {
      url = "github:0xc000022070/zen-browser-flake";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    #plugins list
    avante-nvim = {
      url = "github:yetone/avante.nvim";
      flake = false;
    };
    minuet-ai-nvim = {
      url = "github:milanglacier/minuet-ai.nvim";
      flake = false;
    };
    blink-cmp.url = "github:saghen/blink.cmp";
    vim-translator = {
      url = "github:voldikss/vim-translator";
      flake = false;
    };
    none-ls-nvim = {
      url = "github:nvimtools/none-ls.nvim";
      flake = false;
    };
    nui-nvim = {
      url = "github:MunifTanjim/nui.nvim";
      flake = false;
    };
  };

  outputs = inputs @ {
    self,
    nixpkgs,
    home-manager,
    ags,
    disko,
    sops-nix,
    nur,
    stylix,
    flake-parts,
    ...
  }:
    flake-parts.lib.mkFlake {inherit inputs;} {
      systems = ["x86_64-linux"];
      perSystem = {pkgs, ...}: let
        pkgs-unfree = import inputs.nixpkgs {
          system = pkgs.system;
          config.allowUnfree = true;
        };
      in {
        packages = {
          vscode-fhs = pkgs-unfree.vscode-fhs;
        };
      };

      flake = let
        mkNixosSystem = {
          system,
          host,
          username,
        }:
          nixpkgs.lib.nixosSystem {
            specialArgs = {inherit inputs username host system;};

            modules = [
              disko.nixosModules.default
              sops-nix.nixosModules.sops
              nur.modules.nixos.default
              stylix.nixosModules.stylix
              ./hosts/${host}/config.nix
              ./hosts/${host}/sops.nix
              home-manager.nixosModules.home-manager
              ({
                pkgs,
                nixpkgs-unstable,
                ...
              }: {
                home-manager = {
                  useGlobalPkgs = true;
                  useUserPackages = true;
                  backupFileExtension = "backup";
                  extraSpecialArgs = {inherit inputs username system pkgs nixpkgs-unstable;};
                  users.${username} = {
                    imports = [
                      ./pkgs/home.nix
                    ];
                  };
                };
              })
            ];
          };
      in {
        nixosConfigurations = {
          "lf-nix" = mkNixosSystem {
            system = "x86_64-linux";
            host = "lf-nix";
            username = "lf";
          };

          "viech" = mkNixosSystem {
            system = "x86_64-linux";
            host = "viech";
            username = "lf";
          };
        };
      };
    };
}

config.nix file

{
  config,
  pkgs,
  host,
  username,
  options,
  lib,
  inputs,
  ...
}: let
  inherit (import ./variables.nix) keyboardLayout;
in {
  imports = [
    ./hardware.nix
    ./users.nix
    ./packages.nix
    ../../modules/intel-drivers.nix
    ../../modules/vm-guest-services.nix
    ../../modules/local-hardware-clock.nix
    # ../../pkgs/disable-monitors.nix
    "${inputs.nix-mineral}/nix-mineral.nix"
  ];

  nixpkgs.overlays = [
    inputs.neovim-nightly-overlay.overlays.default
    inputs.mcp-servers-nix.overlays.default
    (final: prev: {
      unstable = import inputs.nixpkgs-unstable {
        inherit (prev) system;
        config.allowUnfree = true;
      };
    })
    # Second overlay: Add your other packages and jupyter-ai.
    # This one can now safely access `final.unstable`.
    (final: prev: {
      claudia = inputs.claudia.packages.${prev.system}.default;
      ags = inputs.ags.packages.${prev.system}.default;
      firefox-addons = inputs.firefox-addons.packages.${prev.system};
    })
    (final: prev: {
      python312 = prev.python312.override {
        packageOverrides = self: super: {
          scann = self.callPackage ../../pkgs/scann.nix {};
          opencv4 = super.opencv4.override { enableGtk2 = true; };
        };
      };
    })
    (final: prev: {
      faiss = prev.faiss.override { cudaSupport = false; };
    })
  ];

  nixpkgs.config.allowUnfree = true;
  security.sudo.wheelNeedsPassword = false; # Allow sudo without password for wheel group
  boot = {
    # kernelPackages = pkgs.linuxPackages_zen; # Performance geared
    kernelPackages = pkgs.linuxPackages_latest; # Best Balance
    # kernelPackages = pkgs.linuxPackages_testing; # Bleeding edge

    kernelParams = [
      "snd-intel-dspcfg.dsp_driver=3"
      "sof-transport-ipc=3"
      "systemd.mask=systemd-vconsole-setup.service"
      "systemd.mask=dev-tpmrm0.device" #this is to mask that stupid 1.5 mins systemd bug
      "nowatchdog"
      # "modprobe.blacklist=sp5100_tco" #watchdog for AMD
      "modprobe.blacklist=iTCO_wdt" #watchdog for Intel
      # "vt.default_red=48,231,166,229,140,244,129,181,98,231,166,229,140,244,129,165"
      # "vt.default_grn=52,130,209,200,170,184,200,191,104,130,209,200,170,184,200,173"
      # "vt.default_blu=70,132,137,144,238,228,190,226,128,132,137,144,238,228,190,206"
    ];

    extraModprobeConfig = ''
      options snd_sof_intel_hda_common dmic_num=4
      options btusb rtk_enable=1
      options rtw88_core disable_lps_deep=Y
      options rtw88_pci disable_aspm=Y
    '';

    initrd = {
      availableKernelModules = ["xhci_pci" "ahci" "nvme" "usb_storage" "uas" "usbhid" "sd_mod" "sdhci_pci"];
      kernelModules = ["kvm-intel"];
    };
    extraModulePackages = [];
    # Needed For Some Steam Games
    kernel.sysctl = {
      "vm.max_map_count" = 2147483642;
    };

    ## BOOT LOADERS: NOTE USE ONLY 1. either systemd or grub
    # Bootloader SystemD
    loader.systemd-boot.enable = true;
    loader.efi.canTouchEfiVariables = true;
    loader.timeout = 10;

    # Make /tmp a tmpfs
    tmp = {
      useTmpfs = false;
      tmpfsSize = "30%";
    };

    # Appimage Support
    binfmt.registrations.appimage = {
      wrapInterpreterInShell = false;
      interpreter = "${pkgs.appimage-run}/bin/appimage-run";
      recognitionType = "magic";
      offset = 0;
      mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff'';
      magicOrExtension = ''\x7fELF....AI\x02'';
    };

    plymouth.enable = true;
  };

  vm.guest-services.enable = false;
  local.hardware-clock.enable = false;

  # networking
  networking = {
    networkmanager.enable = true;
    hostName = "${host}";
    timeServers =
      options.networking.timeServers.default
      ++ [
        "pool.ntp.org"
      ];
  };

  # Set your time zone.
  # services.automatic-timezoned.enable = true; #based on IP location

  #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time.timeZone = "Asia/Jerusalem"; # Set local timezone

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "he_IL.UTF-8";
    LC_IDENTIFICATION = "he_IL.UTF-8";
    LC_MEASUREMENT = "he_IL.UTF-8";
    LC_MONETARY = "he_IL.UTF-8";
    LC_NAME = "he_IL.UTF-8";
    LC_NUMERIC = "he_IL.UTF-8";
    LC_PAPER = "he_IL.UTF-8";
    LC_TELEPHONE = "he_IL.UTF-8";
    LC_TIME = "en_US.UTF-8";
  };

  # Services to start
  services = {
    xserver = {
      enable = false;
      xkb = {
        layout = "${keyboardLayout}";
        variant = "";
      };
    };

    greetd = {
      enable = true;
      vt = 1;
      settings = {
        default_session = {
          user = username;
          command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time";
        };
      };
    };

    smartd = {
      enable = true;
      autodetect = true;
    };

    gvfs.enable = true;
    tumbler.enable = true;

    pipewire = {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
      wireplumber.enable = true;
    };

    pulseaudio.enable = false; #unstable
    udev.enable = true;
    envfs.enable = true;
    dbus.enable = true;

    fstrim = {
      enable = true;
      interval = "weekly";
    };

    libinput.enable = true;
    rpcbind.enable = false;
    nfs.server.enable = false;
    openssh.enable = true;
    flatpak.enable = true;
    blueman.enable = true;

    #hardware.openrgb.enable = true;
    #hardware.openrgb.motherboard = "amd";

    fwupd.enable = false;
    upower.enable = true;
    gnome.gnome-keyring.enable = true;

    syncthing = {
      enable = true;
      user = "${username}";
      dataDir = "/home/${username}";
      configDir = "/home/${username}/.config/syncthing";
      relay.enable = true;
    };
  };

  # zram
  zramSwap = {
    enable = true;
    priority = 100;
    memoryPercent = 30;
    swapDevices = 1;
    algorithm = "zstd";
  };

  powerManagement = {
    enable = true;
    cpuFreqGovernor = "schedutil";
  };

  # Extra Logitech Support
  hardware = {
    logitech.wireless.enable = true;
    logitech.wireless.enableGraphical = true;
  };

  hardware.enableRedistributableFirmware = true;

  hardware.graphics = {
    enable = true;
    enable32Bit = true;
  };

  # Bluetooth
  hardware = {
    bluetooth = {
      enable = true;
      powerOnBoot = true;
      settings = {
        General = {
          Enable = "Source,Sink,Media,Socket";
          Experimental = true;
        };
      };
    };
  };

  # Security / Polkit
  security = {
    rtkit.enable = true;
    polkit.enable = true;
    polkit.extraConfig = ''
       polkit.addRule(function(action, subject) {
         if (
           subject.isInGroup("users")
             && (
               action.id == "org.freedesktop.login1.reboot" ||
               action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
               action.id == "org.freedesktop.login1.power-off" ||
               action.id == "org.freedesktop.login1.power-off-multiple-sessions"
             )
           )
         {
           return polkit.Result.YES;
         }
      })
    '';
  };
  security.pam.services.hyprlock = {};
  # Cachix, Optimization settings and garbage collection automation
  nix = {
    settings = {
      auto-optimise-store = true;
      experimental-features = [
        "nix-command"
        "flakes"
      ];
      substituters = ["https://hyprland.cachix.org"];
      trusted-substituters = ["https://hyprland.cachix.org"];
      trusted-public-keys = ["hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="];
    };
    gc = {
      automatic = true;
      dates = "weekly";
      options = "--delete-older-than 7d";
    };
    nixPath = ["nixpkgs=${inputs.nixpkgs}"];
  };

  # Virtualization / Containers
  virtualisation.libvirtd.enable = false;
  virtualisation.podman = {
    enable = false;
    dockerCompat = false;
    defaultNetwork.settings.dns_enabled = false;
  };

  virtualisation.docker = {
    enable = true;
    rootless.enable = false;
    autoPrune.enable = true;
    enableOnBoot = true;
    extraPackages = [pkgs.docker-buildx];
  };

  console.keyMap = "${keyboardLayout}";

  # For Electron apps to use wayland
  environment = {
    sessionVariables = {
      NIXOS_OZONE_WL = "1"; # Enable Wayland Ozone platform for Electron apps
      ELECTRON_OZONE_PLATFORM_HINT = "wayland"; # Or "AUTO"
      # You might also try:
      ELECTRON_ENABLE_WAYLAND = "1";
      NH_FLAKE = "/home/lf/nix";
      # variables.FZF_SHELL_DIR = "${pkgs.fzf}/share/fzf";
    };
    variables = {
      FZF_SHELL_DIR = "${pkgs.fzf}/share/fzf";
    };
  };

  programs = {
    # Zsh configuration
    zsh = {
      enable = true;
      enableCompletion = true;
      ohMyZsh.enable = false;

      autosuggestions.enable = true;
      syntaxHighlighting.enable = true;
      promptInit = "";
    };
    niri.enable = true;
  };

  systemd.services.user-session-env = {
    script = ''
          export OPENAI_API_KEY="$(cat
      ${config.sops.secrets."api_keys/openai".path})"
          export GEMINI_API_KEY="$(cat
      ${config.sops.secrets."api_keys/gemini".path})"
          export ANTHROPIC_API_KEY="$(cat
      ${config.sops.secrets."api_keys/anthropic".path})"
    '';
  };

  fonts = {
    enableDefaultPackages = false;
    packages = with pkgs; [
      ibm-plex
      inter
      roboto
      aleo-fonts

      # Monospace / Programming Fonts
      fira-code
      jetbrains-mono
      hackgen-nf-font
      roboto-mono
      terminus_font
      victor-mono
      nerd-fonts.im-writing
      nerd-fonts.fantasque-sans-mono
      unstable.maple-mono.NF
      recursive
      cascadia-code

      # Icon / Symbol Fonts
      font-awesome
      fira-code-symbols
      material-icons
      powerline-fonts
      # symbola

      # Noto Fonts
      noto-fonts
      noto-fonts-emoji
      noto-fonts-cjk-sans
      noto-fonts-cjk-serif
      noto-fonts-monochrome-emoji
      noto-fonts-color-emoji
      # Niche/Specific Fonts
      minecraftia
    ];
    /*
       fontconfig = {
      defaultFonts = {
        serif = [
          "Maple Mono NF Italic"
          "Noto Serif"
        ];

        sansserif = [
          "Maple Mono NF Italic"
        ];

        monospace = [
          "Maple Mono NF Italic"
          "Cascadia Code NF"
        ];
      };

      allowBitmaps = false;
    };
    */
  };

  stylix = {
    enable = true;
    enableReleaseChecks = true;
    base16Scheme = ./schemes/catppuccin-frappe.yaml;
    polarity = "dark";
    homeManagerIntegration = {
      autoImport = true;
      followSystem = true;
    };
    targets.nixvim.enable = false;
    cursor = lib.mkDefault {
      name = "catppuccin-mocha-peach-cursors";
      package = pkgs.catppuccin-cursors.mochaPeach;
      size = 24;
    };
    opacity = {
      applications = 1.5;
      desktop = 1.5;
      popups = 1.5;
      terminal = 1.5;
    };
    fonts = {
      serif = {
        package = pkgs.maple-mono.NF;
        name = "Maple Mono NF";
      };

      sansSerif = {
        # package = pkgs.noto-fonts-cjk-sans;
        # name = "Noto Sans CJK JP";
        package = pkgs.maple-mono.NF;
        name = "Maple Mono NF";
      };

      monospace = {
        #        package = pkgs.maple-mono.NF;
        name = "Maple Mono NF";
      };

      emoji = {
        package = pkgs.noto-fonts-color-emoji;
        name = "Noto Color Emoji";
      };

      sizes = {
        applications = 9;
        desktop = 9;
        popups = 9;
        terminal = 9;
      };
    };
  };

  system.stateVersion = "24.11"; 
}

packages.nix

{
  pkgs,
  inputs,
  ...
}:
let
  r-with-packages = pkgs.rWrapper.override {
    packages = with pkgs.rPackages; [
      IRkernel
      tidyverse
      lubridate
      modelr
      caTools
      psych
      devtools
      sandwich
      lemon
      gridExtra
      arm
      broom
      boot
      RcppEigen
      lme4
    ];
  };
in
{
  imports = [
    ../../pkgs/gemini/gemini-cli-lf.nix
  ];
  nixpkgs.config.allowUnfree = true;

  environment.systemPackages =
    (with pkgs; [
      # System Packages
      alsa-utils
      isd # interactively interact with systemd
      baobab
      btrfs-progs
      clang
      mcp-server-fetch
      cpufrequtils
      duf # Utility For Viewing Disk Usage In Terminal
      findutils
      ffmpeg
      pkg-config
      gsettings-qt
      git
      git-credential-manager
      killall
      libappindicator
      libnotify
      openssl # required by Rainbow borders
      pciutils
      wget
      xdg-user-dirs
      xdg-utils
      linux-firmware
      d2

      # (mpv.override {scripts = [mpvScripts.mpris];}) # with tray
      # ranger
      # inputs.zen-browser.packages."${system}".twilight-official
      # Hyprland Stuff
      #ags
      inputs.ags.packages.${pkgs.system}.default
      nix-your-shell
      btop
      brightnessctl # for brightness control
      cava
      cliphist
      loupe
      gnome-system-monitor
      grim
      gtk-engine-murrine # for gtk themes
      hypridle
      imagemagick
      inxi

      ijq
      manix
      mediainfo

      libsForQt5.qtstyleplugin-kvantum # kvantum
      networkmanagerapplet
      nwg-displays
      nvtopPackages.full
      pamixer
      pavucontrol
      playerctl
      polkit_gnome
      libsForQt5.qt5ct
      kdePackages.qt6ct
      kdePackages.qtwayland
      kdePackages.qtstyleplugin-kvantum # kvantum
      rofi-wayland
      slurp
      swappy
      swaynotificationcenter

      unzip
      wallust
      wl-clipboard
      wlogout
      xarchiver
      yad
      yt-dlp

      # --- MY PACKAGES ---
      # Your requested packages
      lutris
      heroic
      bottles
      stow # Manage dotfiles symlinking
      gnome-font-viewer
      fx
      yq-go
      figlet
      ghostty # Terminal
      uv # Python Package Manager & more
      tmux # Terminal Multiplexer
      gedit # Editor Gui
      vlc # Video Player
      obsidian
      foot # terminal
      calibre # ebooks manager
      # nyxt
      # qutebrowser
      nix-init # create pkg from url
      vulnix # vulnerability scanner

      lazycli
      lazydocker
      lazyjournal
      bitwarden-menu
      chromium
      lagrange
      # FROM ZaneyOS
      appimage-run # Needed For AppImage Support
      hyprpicker # Color Picker
      grimblast # Screenshots
      nix-init # Screenshots
      lshw # Detailed Hardware Information
      ncdu # Disk Usage Analyzer With Ncurses Interface
      picard # For Changing Music Metadata & Getting Cover Art
      usbutils # Good Tools For USB Devices
      gcr
      # Dev Stuff
      nixd
      nh
    ])
    ++ (with pkgs.unstable; [
      bc
      curl
      glib # for gsettings to work
      fastfetch
      jq
      nwg-look
      swww
      nix-search-tv
      claude-code
      bitwarden-cli
      ruff
      bitwarden-desktop
      twingate
      hyprls
      lazygit
      pipx
      lm_sensors # Used For Getting Hardware Temps
      sof-firmware
    ])
    ++ [
      r-with-packages # Add the R environment
    ];

  programs = {
    direnv = {
      enable = true;
      nix-direnv.enable = true;
      enableZshIntegration = true;
      enableFishIntegration = true;
      enableBashIntegration = true;
      enableXonshIntegration = true;
    };

    hyprland = {
      enable = true;
      # package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
      portalPackage = pkgs.xdg-desktop-portal-hyprland;
      xwayland.enable = true;
      withUWSM = true;
    };
    # xonsh.enable = false;
    hyprlock.enable = true;
    waybar.enable = true;
    thunar = {
      enable = true;
      # thunar.
      plugins = with pkgs.xfce; [
        exo
        mousepad
        thunar-archive-plugin
        thunar-volman
        tumbler
        #      thunar-vcs-plugin
        thunar-media-tags-plugin
      ];
    };
    virt-manager.enable = false;

    steam = {
      enable = true;
      remotePlay.openFirewall = true;
      dedicatedServer.openFirewall = false;
    };
    firefox.enable = true;
    dconf.enable = true;
    seahorse.enable = true;
    fuse.userAllowOther = true;
    mtr.enable = true;
    gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
    };
  };

  # Extra Portal Configuration
  xdg.portal = {
    enable = true;
    wlr.enable = false;
    extraPortals = [
      pkgs.xdg-desktop-portal-hyprland
      pkgs.xdg-desktop-portal-gtk
    ];
    configPackages = [
      pkgs.xdg-desktop-portal-hyprland
    ];
  };
}

home.nix file

{
  pkgs,
  username,
  ...
}: let
  customWaybar = pkgs.waybar.overrideAttrs (oldAttrs: {
    mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
  });
in {
  imports = [
    ./bat.nix
    ./cli.nix
    # ./emacs.nix
    # ./firefox.nix      # not yet ready
    ./fzf.nix # replaced by television
    ./git.nix
    # ./hyprpanel.nix
    # ./hyprlock.nix
    ./lsd.nix
    # ./mpd.nix
    # ./niriswitcher.nix
    ./nvim
    ./starship.nix
    ./television.nix
    #   ./waybar.nix
    #   ./vscode.nix
    ./zsh.nix
  ];

  programs.hyprpanel.enable = false;

  # Home Manager version
  home = {
    stateVersion = "24.11";

    # User information
    username = username;
    homeDirectory = "/home/${username}";

    # User-specific packages
    packages = [
      (pkgs.python312.withPackages (ps: with ps; [
        # faiss
        tensorboard
        torchvision
        torch
        tsfresh
        optuna
        pyquery
        imbalanced-learn
        scipy
        requests
        rich
        polars
        pandas
        numpy
        matplotlib
        pymilvus
        scann
        pygame
        jupyterlab
        jupyter
        pillow
        opencv-python
        tqdm
        plotly
        pytest
        imageio
        seaborn
        python-dotenv
        regex
        tabulate
        ipykernel
        aiofiles
        pip
        scikit-learn
        scikit-image
        debugpy
        sqlalchemy
        pkgs.pyprland
      ]))
      # jupyter
      # jupyter-all # Jupyter Notebook and JupyterLab with popular extensions
      customWaybar
      pkgs.blender # 3D creation suite
      pkgs.fpp
      # ags
      pkgs.igrep # Improved grep with context and file filtering
      pkgs.base16-shell-preview # Set of shell scripts to change terminal colors using
      pkgs.base16-schemes # Collection of base16 color schemes
      pkgs.unstable.manix
      pkgs.unstable.rmpc
      pkgs.rtaudio # Real-time audio I/O library
      pkgs.erdtree # Visualize directory structure as a tree
      # unstable.opencode
      pkgs.cmake
      # unstable.mpd
      pkgs.meld
      pkgs.normcap
      pkgs.fd
      # ripgrep
      pkgs.repgrep # A more powerful ripgrep with additional features
      pkgs.ripgrep-all
      pkgs.alejandra
      pkgs.unstable.pre-commit
      pkgs.nodejs # Provides npm
      pkgs.kdePackages.okular
      pkgs.vgrep # User-friendly pager for grep/git-grep/ripgrep
      # xonsh # Python-ish, BASHwards-compatible shell
      pkgs.vimPluginsUpdater
      pkgs.vimgolf # Interactive Vim golf game, train you vim skills
      pkgs.rofi-obsidian # Rofi plugin to quickly open Obsidian notes
      pkgs.rofi-rbw-wayland # Rofi-frontend for Bitwarden
      pkgs.wtype
      pkgs.rbw
      pkgs.pinentry-rofi
      pkgs.pinentry
      pkgs.alsa-ucm-conf # maybe this fixed sound issue?
      pkgs.tradingview
      pkgs.emacs-pgtk
      pkgs.neovide
      pkgs.appimage-run
      pkgs.codex # Claude Assistant CLI
      pkgs.claudia
      pkgs.statix # Lints and suggestions for the Nix programming language
      # nur.repos.novel2430.zen-browser-bin # Zen Browser
      # nur.repos."7mind".ibkr-tws     # Interactive Brokers TWS
      # nur.repos.k3a.ib-tws
      pkgs.nixdoc
      pkgs.glow # Beautiful terminal markdown viewer
      pkgs.gum # Terminal-based GUI toolkit
      pkgs.keepassxc # Password manager
      pkgs.keepmenu # Menu for KeePassXC
      pkgs.git-credential-keepassxc # Credential helper for Git
      pkgs.libnotify
      pkgs.papirus-icon-theme
      pkgs.pcmanfm-qt
      pkgs.zed-editor # Code Editor
      pkgs.pnpm # npm package manager
      pkgs.git-filter-repo
      pkgs.sof-tools
      pkgs.fabric-ai
      pkgs.faiss # Command line tool for interacting with Generative AI models
      # (callPackage ./ipython-ai.nix {}).out
    ];

    sessionVariables = {
      P = "$HOME/git/py";
      C = "$HOME/.config";
      G = "$HOME/git";
      R = "$HOME/repos";
      O = "$HOME/Obsidian";
      D = "$HOME/dotfiles";
      N = "$HOME/nix";
      DL = "$HOME/Downloads";
      TERM = "xterm-256color";
      VISUAL = "nvim";
      EDITOR = "nvim";
      OPENAI_API_KEY = "$(cat /run/secrets/api_keys/openai 2>/dev/null || echo '')";
      GEMINI_API_KEY = "$(cat /run/secrets/api_keys/gemini 2>/dev/null || echo '')";
      GOOGLE_API_KEY = "$(cat /run/secrets/api_keys/gemini 2>/dev/null || echo '')";
      ANTHROPIC_API_KEY = "$(cat /run/secrets/api_keys/anthropic 2>/dev/null || echo '')";
      NIXOS_OZONE_WL = 1;
      BASE16_SHELL = "$HOME/.config/base16-shell";
      TERM_ITALICS = "true";
      BAT_THEME = "base16";
      PAGER = "less";
      LESS = "-R";
    };

    file = {
      ".pre-commit-config.yaml" = {
        source = ../.pre-commit-config.yaml; # Path to the file in your dotfiles
        target = ".pre-commit-config.yaml";
      };
      ".gitignore" = {
        text = ''
          keys.txt
          example_config/
          example_config/*
          secrets.pt.yaml
        '';
      };
      ".ipython/extensions/custom_gemini_provider.py".source = ./custom-gemini-provider.py;
    };
  };

  fonts.fontconfig.enable = true;

  xdg = {
    mimeApps = {
      enable = true;
      defaultApplications = {
        "text/markdown" = "code.desktop";
        "text/plain" = "code.desktop";
        "text/x-csv" = "code.desktop";
        "text/x-log" = "code.desktop";
        "text/x-patch" = "code.desktop";
        "text/html" = "firefox.desktop";
        "x-scheme-handler/http" = "firefox.desktop";
        "x-scheme-handler/https" = "firefox.desktop";
        "x-scheme-handler/mailto" = "firefox.desktop";
        "x-scheme-handler/vscode" = "vscode.desktop";
        "image/jpeg" = "loupe.desktop";
        "image/png" = "loupe.desktop";
        "image/gif" = "loupe.desktop";
        "image/bmp" = "loupe.desktop";
        "image/svg+xml" = "loupe.desktop";
        "application/pdf" = "org.kde.okular.desktop";
        "application/xml" = "code.desktop";
        "application/x-yaml" = "code.desktop";
        "application/json" = "code.desktop";
        "image/avif" = "loupe.desktop";
        "audio/*" = ["vlc.desktop"];
        "video/*" = ["vlc.desktop"];
      };
    };
    userDirs = {
      enable = true;
      desktop = "$HOME/Desktop";
      documents = "$HOME/Documents";
      download = "$HOME/Downloads";
      music = "$HOME/Music";
      pictures = "$HOME/Pictures";
      videos = "$HOME/Videos";
    };
    configFile = {
      "nvim/lua" = {
        recursive = true;
        source = ./nvim/lua;
      };
      "mimeapps.list".force = true;
    };
  };
  stylix = {
    enable = true;
    autoEnable = true;
    targets = {
      neovim.enable = false;
      waybar.enable = false;
      wofi.enable = false;
      hyprland.enable = false;
      hyprlock.enable = false;
      vscode = {
        enable = true;
      };
      kitty = {
        enable = true;
        variant256Colors = true;
      };
      font-packages.enable = true;
    };
  };
}