How to get latest version of packages?

i am very new to nix.

I notice most of the packages in nix registry are out of date. eg:

go is at 1.20 when latest is 1.21
bazel is at 6.2.0 when latest is 6.3.2

what is the recommended way to search for and get the latest version of nix packages?

Sometimes it helps to append a version number to the end of the package name. For example: Go has a convention of go_major_minor in nixpkgs that you can use to find specific versions, so go_1_21 will get you the version you want. This convention is a little different for different packages (e.g., Python uses pythonMajorMinor, like python39)

Another option is to search for the package on tools like Nixhub, which aggregates all the current and historic versions for a package on one page. Here’s the page for Go: go | How to install with Nix or Devbox

so i looked at nixhub, but they seem to have hash value in the ‘nixpkgs reference’ field, eg for Bazel: bazel | How to install with Nix or Devbox

how do i use this info to get v6.3.2 of Bazel

I’ve never heard of nixhub, I don’t think it’s an official resource. I think the source of truth for available packages in nixpkgs is NixOS Search. It looks like bazel 6.3.2 is in there.

Since you mentioned the registry, I assume you’re using flakes as opposed to channels. Can you post the output of nix flake metadata nixpkgs and nix flake run nixpkgs#bazel -- --version?

i just have a basic shell.nix file which does packages = [pkgs.go].
i am learning via the guides on nix website.

no idea what flakes or channels are. it seems the latest bazel you pointed to is in the ‘unstable’ channel. how do i use it from there?

Just wanted to point out that you probably use the stable channel. See the unofficial nixos wikipage to channels on how to switch channels.

small update: the docs don’t seem to completely show you how to do it (didn’t find it in either official manual either), so what you want is to

  • list your current channels where one should be called nixpkgs and point to the stable branch (it’s probably the only one)
  • remove it
  • add it again but pointing to unstable url
  • nix-channel --update

the nix-channel --add might be able to overwrite an existing channel, but I’m not sure. In that case the “remove” step can be ignored

(i’m on the phone, thus no code example)

is it possible to have some pkgs from stable channel, but others from unstable channel?

Ah, you were using “registry” in a different sense.

I’m not sure about channels, but you can have packages from different revisions of nixpkgs, which channels are a layer of abstraction over. Check out this link for an introduction to using specific git revisions of nixpkgs in your shell.nix, as opposed to <nixpkgs>, which will be determined by your channels:

Then you can extend this and bring in multiple versions of nixpkgs by git hash using fetchTarball.

  pkgs1 = import (fetchTarball "") {};
  pkgs2 = import (fetchTarball "") {};
  pkgs1.mkShell {
    buildInputs = [ pkgs1.hello pkgs2.cowsay ];

Note that I’ve switched from shell.nix containing a function which returns a derivation to just a derivation, nix-shell also supports this form.

The alternative way is to use a flake. Flakes are nominally an experimental feature, but widely used in practice and unlikely to change significantly. Using a flake for this task would look like this:

# flake.nix
  inputs = {
    nixpkgs2305.url = "github:NixOS/nixpkgs/nixos-23.05";
    nixpkgsUnstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

  outputs = { self, nixpkgs2305, nixpkgsUnstable }: 
      pkgs2305 = nixpkgsUnstable.legacyPackages.x86_64-linux;
      pkgsUnstable = nixpkgsUnstable.legacyPackages.x86_64-linux;
    devShells.x86_64-linux.default = pkgsUnstable.mkShell {
      buildInputs = [ pkgs2305.hello pkgsUnstable.cowsay ];

We can enter the devShell with nix develop (although this won’t work for you out of the box without enabling flakes). We don’t have to specify a specific git revision for nixpkgs-unstable to make this reproducible, even though it’s a moving target. This is because nix will create a lockfile pinning the current version as soon as we build.

I prefer this method, even though there’s more boilerplate involved, because you get a similar UX to other programming language package managers with lockfiles. The pinning is done for you so you don’t need to think about git revisions if you don’t want to, and there are commands for updating your inputs. I recommend this article for a comprehensive introduction to flakes.