NixOSGoOpen Source
Mar 24, 2026

search-nix: From Shell Script to Go TUI in a Weekend

I got tired of opening a browser to search NixOS packages. So I built a CLI that queries search.nixos.org directly.

D
Darius
darius.codes
4 min read

Every time I needed to find a NixOS package, I opened a browser, navigated to search.nixos.org, typed my query, scrolled through results, copied the package name, and switched back to my terminal. Five context switches for something that should be one command.

So I wrote that one command.

The itch

I run NixOS on my homelab and my development machines. Package search is something I do dozens of times a day — checking if a tool exists in nixpkgs, finding the right package name for a binary, comparing versions across channels.

The web interface at search.nixos.org is fine. It’s well-built, it works. But it’s a browser tab. Every search pulls me out of the terminal, breaks my flow, and adds friction to what should be a two-second operation.

The underlying data is served by an Elasticsearch API. If you can query it directly, you don’t need the web UI at all.

The shell prototype

The first version was a shell script. About 50 lines of curl piped through jq:

bash
curl -s "https://search.nixos.org/backend/..." \
  | jq -r '.hits.hits[] | .fields | ...'

It worked. Badly. The output was hard to read, there was no ranking, no highlighting, and parsing Elasticsearch responses in jq is the kind of thing you do once and then immediately regret.

But the prototype proved the concept. The API is public, the response format is predictable, and a CLI tool that wraps it could be genuinely useful.

Rewriting in Go

Go was the obvious choice for a CLI tool. Fast compilation, single binary output, no runtime dependencies. Perfect for something you want to nix run without pulling in half the internet.

The core is straightforward — build the Elasticsearch query, POST it, parse the response. The interesting parts are in the details:

Channel detection. The tool auto-detects your NixOS channel from nixos-version. If you’re on 25.11, it searches 25.11. If detection fails, it defaults to unstable. You can override with -c unstable or -c 25.11.

Result ranking. The best match goes to the bottom of the output, not the top. This is deliberate — when you’re in a terminal, the most relevant result should be the last thing printed, right above your cursor. No scrolling needed.

Exact matching. If a package name exactly matches your query, it gets a * marker so you can spot it instantly.

Term highlighting. Your search terms are highlighted in the output so you can scan results quickly. Each term gets matched individually, not just as a substring of the full query.

The TUI

The CLI mode covers 80% of my usage. But sometimes I want to browse, expand details, compare packages. That’s where the TUI comes in.

Pressing -t launches an interactive interface. Arrow keys to navigate, Enter to expand a result, y to copy the package name, e for the nix-env install command, p for the nix profile command. You can press r to launch a nix-shell with the selected package directly — useful for trying something before committing to an install.

The details view shows homepage, license, description, and all programs provided by the package. Long descriptions word-wrap properly. You can pin expanded entries so they stay open while you browse others, or press a to expand everything at once.

Channel switching works inline — press c to cycle through channels without restarting. The search re-executes automatically.

Packaging as a Nix flake

The tool is packaged as a Nix flake, which means installation is:

bash
nix run github:DariusCorvus/search-nix -- your-query

Or add it as a flake input for permanent installation. No Go toolchain needed, no go install, no GOPATH. The flake handles the build and makes the binary available.

This is the kind of thing that makes Nix worth the learning curve. Package distribution is a solved problem — you declare the build, and anyone with Nix can run it. No Docker, no CI artifacts, no release pages.

What’s next

The tool is about a week old and already does what I need. There are a few things I’m considering:

  • Fuzzy matching for typos and partial names
  • Options search alongside packages — NixOS configuration options are searchable through the same API
  • Cache for frequently searched terms

But honestly, it might be done. The best tools are the ones that do one thing and then get out of the way.

The code is at github.com/DariusCorvus/search-nix.

ende