Cache the nix package list, query and sort by relevance.
Find installable packages at lightning speed and sort the result by relevance, split by ...
- indirect hits - packages that contain the search string,
- direct hits - packages that start with the search string,
- exact hits - the package that matches your exact search string,
... in configurable individual colors, optionally separated by a newline. Have a look:
This is the safest way to run a well-tested nps version from the official repository.
nix run nixpkgs#nps -- COMMAND_LINE_OPTIONSnix --extra-experimental-features "nix-command flakes" run nixpkgs#nps -- COMMAND_LINE_OPTIONSAdd nps to your systemPackages in configuration.nix:
environment.systemPackages = with pkgs; [
nps
...
];If you want the latest features before they hit nixpkgs.
nix run github:OleMussmann/nps -- COMMAND_LINE_OPTIONSnix --extra-experimental-features "nix-command flakes" run github:OleMussmann/nps -- COMMAND_LINE_OPTIONS
⚠️ The way of installing third-party flakes is highly dependent on your personal configuration. As far as I know there is no standardized, canonical way to do this. Instead, here is a generic approach via overlays. You will need to adapt it to your config files.
Add nps to your inputs:
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
# Nix Package Search - nps
nps.url = "github:OleMussmann/nps";
nps.inputs.nixpkgs.follows = "nixpkgs";
};Add an overlay to your outputs:
outputs = { self, nixpkgs, ... }@inputs:
let
third-party-packages = final: prev: {
nps = inputs.nps.packages.${prev.system}.default;
<other third party flakes you have>
};
in {
nixosConfigurations."<hostname>" = nixpkgs.lib.nixosSystem {
system = "<your_system_architecture>";
modules = [
({ config, pkgs, ... }: { nixpkgs.overlays = [ third-party-packages ]; })
./configuration.nix
];
};
};Finally, add nps to your systemPackages in configuration.nix:
environment.systemPackages = with pkgs; [
other_packages
third-party-packages.nps
...
];Add nps to your systemPackages in configuration.nix:
environment.systemPackages = with pkgs; [
other_packages
# Nix Package Search - nps:
(builtins.getFlake "github:OleMussmann/nps").packages.${builtins.currentSystem}.nps
...
];- Clone this repository and
cd npsinto it. - Build with
cargo build --release. Dependencies needed:gcc,cargo - Copy or symlink the
target/release/npsexecutable to a folder in yourPATH, or include it in yourPATH.
Instead of running nps -r (or nps -e -r for using the nix "experimental" features a.k.a flakes) by hand every once in a while to refresh the package cache, or you can set up a systemd timer at regular intervals. If you automate it, make sure to do so with your local user environment.
systemd.timers."refresh-nps-cache" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "weekly"; # or however often you'd like
Persistent = true;
Unit = "refresh-nps-cache.service";
};
};
systemd.services."refresh-nps-cache" = {
# Make sure `nix` and `nix-env` are findable by systemd.services.
path = ["/run/current-system/sw/"];
serviceConfig = {
Type = "oneshot";
User = "REPLACE_ME"; # ⚠️ replace with your "username" or "${user}", if it's defined
};
script = ''
set -eu
echo "Start refreshing nps cache..."
# ⚠️ note the use of overlay (as described above), adjust if needed
# ⚠️ use `nps -dddd -e -r` if you use flakes
${pkgs.third-party-packages.nps}/bin/nps -r -dddd
echo "... finished nps cache with exit code $?."
'';
};-
Test the service by starting it by hand and checking the logs.
sudo systemctl start refresh-nps-cache.service journalctl -xeu refresh-nps-cache.service
-
Test your timer by letting it run, for example, every 5 minutes. Adjust the timers as follows.
-OnCalendar = "weekly"; +OnBootSec = "5m"; +OnUnitActiveSec = "5m";
Check the logs if it ran successfully.
journalctl -xeu refresh-nps-cache.service
⚠️ Don't forget to revert your changes afterwards.
nps PACKAGE_NAMEsearches the cache file for packages matching thePACKAGE_NAMEsearch string.- The cache is created on the first call. Be patient, it might take a while. This is done under the hood by capturing the output of
nix-env -qaP(ornix search nixpkgs ^for "experimental"/flake mode). Subsequent queries are much faster.
Find SEARCH_TERM in available nix packages and sort results by relevance.
List up to three columns, the latter two being optional:
PACKAGE_NAME <PACKAGE_VERSION> <PACKAGE_DESCRIPTION>
Matches are sorted by type. Show 'indirect' matches first, then 'direct' matches, and finally 'exact' matches.
indirect fooSEARCH_TERMbar (SEARCH_TERM appears in any column)
direct SEARCH_TERMbar (PACKAGE_NAME starts with SEARCH_TERM)
exact SEARCH_TERM (PACKAGE_NAME is exactly SEARCH_TERM)
Usage: nps [OPTIONS] [SEARCH_TERM]
Arguments:
[SEARCH_TERM]
Search for any SEARCH_TERM in package names, description or versions
Options:
-c, --color[=<COLOR>]
Highlight search matches in color
[env: NIX_PACKAGE_SEARCH_COLOR_MODE=]
[default: auto]
[aliases: colour]
[possible values: auto, always, never]
-C, --columns[=<COLUMNS>]
Choose columns to show
[env: NIX_PACKAGE_SEARCH_COLUMNS=]
[default: all]
Possible values:
- all: Show all columns
- none: Show only PACKAGE_NAME
- version: Also show PACKAGE_VERSION
- description: Also show PACKAGE_DESCRIPTION
-d, --debug...
Turn debugging information on
Use up to four times for increased verbosity
-e, --experimental[=<EXPERIMENTAL>]
Use experimental flakes
[env: NIX_PACKAGE_SEARCH_EXPERIMENTAL=]
[default: false]
[possible values: true, false]
-f, --flip[=<FLIP>]
Flip the order of matches and sorting
[env: NIX_PACKAGE_SEARCH_FLIP=]
[default: false]
[possible values: true, false]
-i, --ignore-case[=<IGNORE_CASE>]
Ignore case
[env: NIX_PACKAGE_SEARCH_IGNORE_CASE=]
[default: true]
[possible values: true, false]
-m, --multi-line[=<MULTI_LINE>]
Multi line
Print search matches on two lines, followed by a newline:
> PACKAGE_NAME PACKAGE_VERSION
> PACKAGE_DESCRIPTION
>
[env: NIX_PACKAGE_SEARCH_MULTI_LINE=]
[default: false]
[possible values: true, false]
-q, --quiet[=<QUIET>]
Suppress non-debug messages
[env: NIX_PACKAGE_SEARCH_QUIET=]
[default: false]
[possible values: true, false]
-r, --refresh
Refresh package cache and exit
-s, --separate[=<SEPARATE>]
Separate match types with a newline
Only applicable when --multi-line=false
[env: NIX_PACKAGE_SEARCH_PRINT_SEPARATOR=]
[default: true]
[possible values: true, false]
-t, --truncate[=<TRUNCATE>]
Separate match types with a newline
Only applicable when --multi-line=false
[env: NIX_PACKAGE_SEARCH_TRUNCATE=]
[default: false]
[possible values: true, false]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print versionApart from command line flags, nps can be configured with environment variables. You can set these in your config file. Below are the defaults. Uncomment and change the ones you need.
environment.sessionVariables = {
#NIX_PACKAGE_SEARCH_COLOR_MODE = "auto";
#NIX_PACKAGE_SEARCH_COLUMNS = "all";
#NIX_PACKAGE_SEARCH_EXPERIMENTAL = "false"; # Set to "true" for flakes
#NIX_PACKAGE_SEARCH_FLIP = "false";
#NIX_PACKAGE_SEARCH_IGNORE_CASE = "true";
#NIX_PACKAGE_SEARCH_MULTI_LINE = "false";
#NIX_PACKAGE_SEARCH_PRINT_SEPARATOR = "true";
#NIX_PACKAGE_SEARCH_QUIET = "false";
#NIX_PACKAGE_SEARCH_TRUNCATE = "false";
#NIX_PACKAGE_SEARCH_CACHE_FOLDER_ABSOLUTE_PATH = "/home/YOUR_USERNAME/.nix-package-search";
#NIX_PACKAGE_SEARCH_EXACT_COLOR = "magenta";
#NIX_PACKAGE_SEARCH_DIRECT_COLOR = "blue";
#NIX_PACKAGE_SEARCH_INDIRECT_COLOR = "green";
};Use the experimental nix search command. It pulls information from the nix flake registries instead of nix channels. This is useful if no channels are in use, or channels are not updated regularly.
- default: false
- possible values: true, false
Flip the order of matches? By default most relevant matches appear below, which is easier to read with long output. Flipping shows most relevant matches on top.
- default: false
- possible values: true, false
Absolute path of the cache folder
- default: /home/YOUR_USERNAME/.nix-package-search
- possible values: path
Choose columns to show: PACKAGE_NAME plus any of PACKAGE_VERSION or PACKAGE_DESCRIPTION
- default: all
- possible values: all, none, version, description
Color of EXACT matches, match SEARCH_TERM in PACKAGE_NAME
- default: magenta
- possible values: black, blue, green, red, cyan, magenta, yellow, white
Color of DIRECT matches, match SEARCH_TERMbar in PACKAGE_NAME
- default: blue
- possible values: black, blue, green, red, cyan, magenta, yellow, white
Color of INDIRECT matches, match fooSEARCH_TERMbar in any column
- default: green
- possible values: black, blue, green, red, cyan, magenta, yellow, white
Show search matches in color
- default: auto (only show color if stdout is in terminal, suppress if e.g. piped)
- possible values: always, never, auto
Separate matches with a newline?
- default: true
- possible values: true, false
Suppress non-debug messages?
- default: false
- possible values: true, false
Search ignore capitalization for the search?
- default: true
- possible values: true, false
Print search matches on multiple lines?
> PACKAGE_NAME PACKAGE_VERSION
> PACKAGE_DESCRIPTION
>
- default: false
- possible values: true, false
Truncate lines longer than terminal width?
> PACKAGE_NAME PACKAGE_VERSION PACKAGE_DESC…
- default: false
- possible values: true, false
- Check existing issues or open a new one to suggest a feature or report a bug.
- Fork the repository, check the DEVELOPMENT.md and make your changes
- Open a pull request
