# Nix-search: A faster, better nix search

**URL:** https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568
**Category:** Announcements
**Created:** [July 6, 2024, 2:22pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568 "2024-07-06T14:22:51Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 6, 2024, 2:22pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/1 "2024-07-06T14:22:51Z")

</div>

Since Nix 2.4’s release, I’ve always been fed up at how `nix search` has become so much slower than Nix 2.3’s search, and everyone kept telling me to use [search.nixos.org](https://search.nixos.org)! So I made a really fast `nix search` alternative called `nix-search`:

 ![image](https://discourse.nixos.org/uploads/default/original/3X/8/1/81023b04f6befda2b33f15ed027f8e2d0f96c9a4.jpeg)  
[![asciicast](https://asciinema.org/a/656954.svg)](https://asciinema.org/a/656954)

The goal of `nix-search` is to be as similar to Nix 2.3’s `nix search` as possible while also not taking a very long time to index and search. For example, on my computer, indexing takes ~20s while searching takes way less than 1s:

```sh
―❤―▶ time nix-search --index

real	0m21.760s
user	2m36.436s
sys 0m30.729s

―❤―▶ time nix-search firefox > /dev/null

real	0m0.033s
user	0m0.028s
sys 0m0.006s

```

`nix-search` supports both Nix flakes and channels, but it uses the `<nixpkgs>` channel by default. You may override this by doing `--channel '<nixpkgs>'` or `--flake nixpkgs` when indexing.

`nix-search` also adheres to `$PAGER`, so you can easily use your favorite pager. For example, to use `nix-search` with `most`:

```sh
nix-shell -p most
PAGER=most nix search firefox

```

Internally, `nix-search` is powered by an actual search database called [Bluge](https://github.com/blugelabs/bluge), so performance is really good while the searching itself is very flexible. For example, you may run `nix-search` with `--exact=false` which turns off the exact match filtering:

```sh
―❤―▶ nix-search --exact=true python | head -n2 # default
- nixpkgs.pythonFull (2.7.18.8)
  A high-level dynamically-typed programming language

―❤―▶ nix-search --exact=false python | head -n2
- nixpkgs.pyp (1.2.0)
  Easily run Python at the shell

```

## Installation

> **Installation (non-Flakes)**
>
> `nix-search` comes with a `default.nix` that has itself packaged. To install it, simply fetch it from GitHub and `import` it:
> 
> ```nix
> let
> nix-search = import (pkgs.fetchFromGitHub {
> owner = "diamondburned";
> repo = "nix-search";
> rev = "<REV>";
> sha256 = "<SHA256>";
> });
> in
> 
> {
> environment.systemPackages = [nix-search];
> }
> 
> ```

> **Installation (Flakes)**
>
> `nix-search` comes with a `flake.nix` that contains itself in `nix-search.packages.${system}.default`:
> 
> ```auto
> git+file:///home/diamond/Scripts/nix-search?ref=refs/heads/main&rev=98c54882df337dc15387ac725543784a31f64935
> └───packages
> ├───aarch64-darwin
> │ └───default omitted (use '--all-systems' to show)
> ├───aarch64-linux
> │ └───default omitted (use '--all-systems' to show)
> ├───x86_64-darwin
> │ └───default omitted (use '--all-systems' to show)
> └───x86_64-linux
> └───default: package 'nix-search-98c54882df337dc15387ac725543784a31f64935'
> 
> ```

> **Installation (using Go)**
>
> Make sure that your `$GOBIN` is in your `$PATH`, then run:
> 
> ```sh
> go install libdb.so/nix-search/cmd/nix-search@latest
> 
> ```

**GitHub Repository** : [diamondburned/nix-search](https://github.com/diamondburned/nix-search)

---

<div class="post-metadata">

### Author: ![emily](https://discourse.nixos.org/user_avatar/discourse.nixos.org/emily/32/1628_2.png) [@emily](https://discourse.nixos.org/u/emily)
#### Post date: [July 6, 2024, 2:44pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/2 "2024-07-06T14:44:10Z")

</div>

Thanks, I was just looking for something like this the other day!

It wasn’t clear to me from a quick skim of your code – do you know about the `packages.json.br` output of the [`tarball` job](https://hydra.nixos.org/job/nixpkgs/trunk/tarball)? That lets you delegate all the work of actually evaluating the package set to Hydra, so it should hopefully be considerably faster to index if your current approach involves calling into Nix proper.

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 6, 2024, 3:18pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/3 "2024-07-06T15:18:21Z")

</div>

I actually had no idea… Currently, I’m invoking `nix` for every attrset and using goroutines to parallelize indexing them.

This Hydra output seems really cool! Can I assume that there will be a Hydra output for every Nixpkgs commit, or is there a specific rule for that?

---

<div class="post-metadata">

### Author: ![Aleksanaa](https://discourse.nixos.org/user_avatar/discourse.nixos.org/aleksanaa/32/12953_2.png) [@Aleksanaa](https://discourse.nixos.org/u/Aleksanaa)
#### Post date: [July 6, 2024, 3:23pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/4 "2024-07-06T15:23:14Z")

</div>

My impression of you is still of the dissent developer, but didn’t expect you also have done many other interesting tools! Appreciate it very much!

---

<div class="post-metadata">

### Author: ![emily](https://discourse.nixos.org/user_avatar/discourse.nixos.org/emily/32/1628_2.png) [@emily](https://discourse.nixos.org/u/emily)
#### Post date: [July 6, 2024, 3:44pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/5 "2024-07-06T15:44:25Z")

</div>

Every Nixpkgs and NixOS channel update is gated on the `tarball` job, which is part of the channel release process. So as long as someone is on a revision that has been part of a channel, there should be a corresponding `packages.json.br` cached. However, you don’t need to think about Hydra at all; you should just be able to try to build it from `release.nix`, which will be substituted as long as all the parameters match up correctly or built as necessary, like any other package. Although that would end up also downloading the actual tarballs as well… I don’t know if there’s a particularly nice interface to get a `hydra-build-products` file, but someone who is more familiar with Hydra than me might.

---

<div class="post-metadata">

### Author: ![MagicRB](https://discourse.nixos.org/user_avatar/discourse.nixos.org/magicrb/32/6884_2.png) [@MagicRB](https://discourse.nixos.org/u/MagicRB)
#### Post date: [July 6, 2024, 3:56pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/6 "2024-07-06T15:56:53Z")

</div>

This is actually very cool! I’ve been wanting to look for something that could give me [seach.nixos.org](http://seach.nixos.org) like output locally, espcially inside emacs, is it possible to add json output this? Then I could invoke it from Emacs and format it nicely into a buffer 😃 . But in any case, looks great, I’ll try it out and run it with `async-shell-command` for now

---

<div class="post-metadata">

### Author: ![emily](https://discourse.nixos.org/user_avatar/discourse.nixos.org/emily/32/1628_2.png) [@emily](https://discourse.nixos.org/u/emily)
#### Post date: [July 6, 2024, 4:14pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/7 "2024-07-06T16:14:15Z")

</div>

There’s also this, by the way, in case anyone is like yesterday‐me and hadn’t heard of it before: [GitHub - peterldowns/nix-search-cli: CLI for searching packages on search.nixos.org](https://github.com/peterldowns/nix-search-cli). That’s just querying over the network, though.

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 6, 2024, 4:50pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/8 "2024-07-06T16:50:01Z")

</div>

v0.3.0 has `--json` now!

---

<div class="post-metadata">

### Author: ![ghpzin](https://discourse.nixos.org/user_avatar/discourse.nixos.org/ghpzin/32/7848_2.png) [@ghpzin](https://discourse.nixos.org/u/ghpzin)
#### Post date: [July 6, 2024, 10:26pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/9 "2024-07-06T22:26:26Z")

</div>

Not sure if that is what you meant, but you can download `packages.json.br` from [https://releases.nixos.org/](https://releases.nixos.org/) with corresponding channel and commit, thought it’s quite big (200-300mb).  
Current latest `nixos-unstable`:  
[nixos-unstable release nixos-24.11pre647193.9f4128e00b0a](https://releases.nixos.org/nixos/unstable/nixos-24.11pre647193.9f4128e00b0a)  
direct link to `packages.json.br`  
(do not click in browser as is, at least firefox tries to open it instead of downloading by default and lags):  
[https://releases.nixos.org/nixos/unstable/nixos-24.11pre647193.9f4128e00b0a/packages.json.br](https://releases.nixos.org/nixos/unstable/nixos-24.11pre647193.9f4128e00b0a/packages.json.br)

---

<div class="post-metadata">

### Author: ![waffle8946](https://discourse.nixos.org/user_avatar/discourse.nixos.org/waffle8946/32/27221_2.png) [@waffle8946](https://discourse.nixos.org/u/waffle8946)
#### Post date: [July 7, 2024, 1:36am UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/10 "2024-07-07T01:36:22Z")

</div>

After trying just about every alternative I know of, even rippkgs and nh, nothing seems to come close to this one in thoughtful design and performance. Thank you for making and sharing this!

---

<div class="post-metadata">

### Author: ![fzakaria](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fzakaria/32/2643_2.png) [@fzakaria](https://discourse.nixos.org/u/fzakaria)
#### Post date: [July 7, 2024, 5:07am UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/11 "2024-07-07T05:07:53Z")

</div>

Is this nix-index and nix-locate ?

Seems closer to those two tools than “nix search”

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 7, 2024, 6:19am UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/12 "2024-07-07T06:19:45Z")

</div>

Not quite. `nix-index` is meant to search for paths in packages, while `nix search` searches the package list itself. The only similarity to `nix-index` is the fact that it indexes, but that’s normal to do.

---

<div class="post-metadata">

### Author: ![emily](https://discourse.nixos.org/user_avatar/discourse.nixos.org/emily/32/1628_2.png) [@emily](https://discourse.nixos.org/u/emily)
#### Post date: [July 7, 2024, 7:37am UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/13 "2024-07-07T07:37:08Z")

</div>

It’s actually under 6 MiB to download, smaller than the Nixpkgs checkout itself; it just inflates massively in size when decompressed. You’d want to stream the decompression directly into the indexer.

---

<div class="post-metadata">

### Author: ![aiono](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@aiono](https://discourse.nixos.org/u/aiono)
#### Post date: [July 7, 2024, 10:58am UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/14 "2024-07-07T10:58:36Z")

</div>

Hi, I tried to install this as non-flake via home manager, but it doesn’t seem to add any binaries to path. My code is:

```nix
{ pkgs, ... }:

let
  nix-search = import (pkgs.fetchFromGitHub {
    owner = "diamondburned";
    repo = "nix-search";
    rev = "v0.3.1";
    sha256 = "sha256-2N1xy9BK9o7j/vk42Pg/nvDjDt7nZlannCLCcS8Puuk=";
  });
in
{
  home.packages = [nix-search];
}

```

Doesn’t add any program called `nix-search`.

---

<div class="post-metadata">

### Author: ![fgaz](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fgaz/32/103_2.png) [@fgaz](https://discourse.nixos.org/u/fgaz)
#### Post date: [July 7, 2024, 4:16pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/15 "2024-07-07T16:16:02Z")

</div>

Does this also improve the memory usage? `nix search` has a maximum resident set size (measured with `time -v`) of 4GB…

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 7, 2024, 4:29pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/16 "2024-07-07T16:29:32Z")

</div>

Not a lot here!

```plaintext
Command being timed: "nix-search firefox"
User time (seconds): 0.02
System time (seconds): 0.00
Percent of CPU this job got: 2%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.12
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 14080
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 1850
Voluntary context switches: 224
Involuntary context switches: 16
Swaps: 0
File system inputs: 256
File system outputs: 8
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

```

---

<div class="post-metadata">

### Author: ![fgaz](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fgaz/32/103_2.png) [@fgaz](https://discourse.nixos.org/u/fgaz)
#### Post date: [July 7, 2024, 4:30pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/17 "2024-07-07T16:30:24Z")

</div>

Thanks! What about `nix-search --index`?

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 7, 2024, 4:32pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/18 "2024-07-07T16:32:44Z")

</div>

That gave me `Maximum resident set size (kbytes): 2530016`, though I’m wondering if this includes subprocesses as well, as `nix-search --index` works by shelling out to `nix` for most of its work.

---

<div class="post-metadata">

### Author: ![fgaz](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fgaz/32/103_2.png) [@fgaz](https://discourse.nixos.org/u/fgaz)
#### Post date: [July 7, 2024, 4:41pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/19 "2024-07-07T16:41:56Z")

</div>

Half the size, nice 🙂

It does include subprocesses, as it should imo.

I think search would benefit from a custom memory management strategy. What probably happens is that nix keeps all evaluated `meta`s in memory in case it will need them again even though in this case the chance of reusing them is negligible. Evaluating metas one by one instead of all at once could reduce memory usage with only a small performance impact.

---

<div class="post-metadata">

### Author: ![diamondburned](https://discourse.nixos.org/user_avatar/discourse.nixos.org/diamondburned/32/1797_2.png) [@diamondburned](https://discourse.nixos.org/u/diamondburned)
#### Post date: [July 7, 2024, 4:44pm UTC](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568/20 "2024-07-07T16:44:17Z")

</div>

Right, and I was surprised to see the index gone as well, as it makes complete sense for something like search!

[Next page](https://discourse.nixos.org/t/nix-search-a-faster-better-nix-search/48568.md?page=2)
