Nix User Repository (NUR)

repository·main·Indexed 23 days ago

https://github.com/nix-community/nur

A community-driven meta repository for Nix packages that allows users to share and install community-contributed Nix expressions via a decentralized namespace. It supports integration with NixOS, Home Manager, and Flakes, providing a way to access new packages and modules without waiting for Nixpkgs reviews.

Tokens
2.9K
Snippets
7
Records
14
Agent score
34%

What's inside NUR

  1. Provide NixOS, Home Manager, and Darwin modules in NUR

    main

    NUR repositories can host more than just packages. To make modules discoverable, place them in specific attributes within your repository's default.nix:

    • NixOS modules: Use the nixosModules attribute. Accessible via nur.repos.<repo>.modules.nixos.<module> in flakes.
    • Home Manager modules: Use the homeModules attribute. Accessible via nur.repos.<repo>.modules.homeManager.<module> in flakes.
    • Darwin (nix-darwin) modules: Use the darwinModules attribute. Accessible via nur.repos.<repo>.modules.darwin.<module> in flakes.
    • flake-parts modules: Use the flakeModules attribute. Accessible via nur.repos.<repo>.modules.flake.<module> in flakes.

    Note: Modules should be defined as paths, not functions, to avoid import conflicts.

    Example default.nix for modules:

    { pkgs }: {
      nixosModules = import ./modules;
      homeModules = import ./hm-modules;
    }
    { pkgs }: {
      nixosModules = import ./modules;
    }
  2. Provide Overlays and Library functions in NUR

    main

    You can extend your NUR repository to include reusable Nix logic:

    • Overlays: Use the overlays attribute. Each overlay should be a valid Nix overlay (e.g., self: super: { ... }).
    • Library functions: Use the lib attribute to provide reusable functions for users.

    Example default.nix for overlays and lib:

    { pkgs }: {
      overlays = {
        my-overlay = import ./my-overlay;
      };
      lib = {
        myFunc = x: x + 1;
      };
    }
    { pkgs }: 
    with pkgs.lib; 
    {
      lib = {
        hexint = x: hexvals.${toLower x};
        hexvals = listToAttrs (imap (i: c: { name = c; value = i - 1; }) (stringToCharacters "0123456789abcdef"));
      };
    }
  3. Add your repository to NUR

    main

    To make your repository available via NUR, you must add it to the repos.json file in the NUR repository.

    Steps:

    1. Clone the NUR repository.
    2. Edit repos.json to include your repository's name and URL.
    3. (Optional) Use the file key to point to a specific Nix file if it is not default.nix at the root.
    4. (Optional) Set submodules: true if your repository uses Git submodules.
    5. Run ./bin/nur format-manifest to ensure alphabetical sorting.
    6. Commit repos.json (but do not commit repos.json.lock).
    7. Submit a Pull Request to the NUR repository.

    Example repos.json entry:

    {
        "repos": {
            "my-repo": {
                "url": "https://github.com/user/my-repo",
                "file": "subdir/default.nix",
                "submodules": true
            }
        }
    }
    {
        "repos": {
            "mic92": {
                "url": "https://github.com/Mic92/nur-packages"
            },
            "<fill-your-repo-name>": {
                "url": "https://github.com/<your-user>/<your-repo>"
            }
        }
    }
  4. Integrate NUR with Home Manager

    main

    Using Flakes

    If you are using Flakes, you can access Home Manager modules directly from the NUR input.

    # In your Home Manager configuration
    {
      imports = lib.attrValues nur.repos.moredhel.modules.homeManager;
    
      services.unison = {
        enable = true;
        profiles = {
          org = {
            src = "/home/moredhel/org";
            dest = "/home/moredhel/org.backup";
            extraArgs = "-batch -watch -ui text -repeat 60 -fat";
          };
        };
      };
    }

    Without Flakes

    If you are not using Flakes, you must manually import the NUR repository using fetchTarball to access the modules.

    let
      nur-no-pkgs = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") {};
    in
    {
      imports = lib.attrValues nur-no-pkgs.repos.moredhel.homeModules;
    }
  5. Install NUR using Flakes

    main

    To use NUR in a Flake-based setup, add it to your inputs. You should use inputs.nixpkgs.follows = "nixpkgs"; to ensure NUR uses the same Nixpkgs instance as your project. Once included, you can access NUR via its overlay (nur.overlays.default) or through legacyPackages.<system>.

    Note: When using Flakes, you can access NUR modules directly in your NixOS configuration or Home Manager imports.

    {
      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
        nur = {
          url = "github:nix-community/NUR";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
    };
  6. Access NUR packages and repositories

    main

    Once NUR is installed, packages are accessed via the nur.repos.<contributor>.<package> namespace.

    Warning: NUR packages are community-contributed and are not reviewed by Nixpkgs members. It is recommended to check expressions before installing them.

    Common usage patterns:

    Using nix-shell:

    $ nix-shell -p nur.repos.mic92.hello-nur

    Using nix-env:

    $ nix-env -f '<nixpkgs>' -iA nur.repos.mic92.hello-nur

    In NixOS configuration.nix:

    # configuration.nix
    environment.systemPackages = with pkgs; [
      nur.repos.mic92.hello-nur
    ];
  7. Trigger a NUR repository update

    main

    NUR typically checks for repository updates once a day via GitHub Actions. To force an update immediately after pushing changes to your repository, use the NUR update service via a POST request.

    Command:

    curl -XPOST https://nur-update.nix-community.org/update?repo=<your-repo-name>
    curl -XPOST https://nur-update.nix-community.org/update?repo=mic92
  8. Create a NUR package repository

    main

    To host packages on NUR, create a repository containing a default.nix at the top level. The repository must return a set of Nix derivations and take a pkgs argument.

    Important Rules:

    • Do not use with import <nixpkgs> {};. Instead, use the provided pkgs argument for all dependencies.
    • Each package should be a directory containing its own default.nix.
    • Use pkgs.callPackage to compose your package set.
    • For development, you can provide a default value for pkgs (e.g., pkgs ? import <nixpkgs> {}).

    Example Repository Structure (default.nix):

    { pkgs ? import <nixpkgs> {} }:
    {
      hello-nur = pkgs.callPackage ./hello-nur {};
    }
    { pkgs }: 
    {
      hello-nur = pkgs.callPackage ./hello-nur {};
    }
  9. Override NUR repositories for testing

    main

    If you want to test changes to a NUR repository locally or before they are published, you can use repoOverrides.

    Using packageOverrides

    In your Nix configuration, use the repoOverrides argument within the nur package.

    { 
      packageOverrides = pkgs: {
        nur = import <NUR_SOURCE> { 
          inherit pkgs; 
          repoOverrides = { 
            mic92 = import ../local-nur-packages { inherit pkgs; }; 
          }; 
        };
      };
    }

    Using Flakes (Experimental)

    In a Flake, you can override repositories via packageOverrides or as a Nixpkgs overlay.

    Via Overlay:

    { 
      modules = [ 
        { 
          nixpkgs.overlays = [ 
            (final: prev: { 
              nur = import nur { 
                nurpkgs = prev; 
                pkgs = prev; 
                repoOverrides = { paul = import paul { pkgs = prev; }; }; 
              }; 
            }) 
          ]; 
        } 
      ]; 
    }

    Note: When using Flakes for overrides, the target repository must contain both a default.nix and a flake.nix.

    { 
      packageOverrides = pkgs: {
        nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") { 
          inherit pkgs; 
          repoOverrides = { 
            mic92 = import ../nur-packages { inherit pkgs; }; 
          }; 
        };
      };
    }
  10. Use NUR modules in NixOS Flakes

    main

    NUR provides modules that can be imported directly into your NixOS configuration. You can use the default NUR overlay or import specific contributor modules.

    {
      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
        flake-utils.url = "github:numtide/flake-utils";
        nur = {
          url = "github:nix-community/NUR";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
    
      outputs = { self, nixpkgs, nur }: {
        nixosConfigurations.myConfig = nixpkgs.lib.nixosSystem {
          # ...
          modules = [
            # Adds the NUR overlay
            nur.modules.nixos.default
            # NUR modules can be imported directly:
            nur.repos.iopq.modules.nixos.xraya
            # Or via legacyPackages (legacy path):
            # nur.legacyPackages."${system}".repos.iopq.modules.xraya
          ];
        };
      };
    }
  11. Pin NUR to a specific version

    main

    Using builtins.fetchTarball without a sha256 only caches the download for 1 hour. To ensure reproducible builds and avoid constant internet access, pin NUR to a specific commit by providing a URL to the archive and its corresponding sha256 hash.

    1. Choose a version from NUR Commits.
    2. Get the hash by running nix-prefetch-url --unpack <url> on the archive URL.
    builtins.fetchTarball {
      url = "https://github.com/nix-community/NUR/archive/3a6a6f4da737da41e27922ce2cfacf68a109ebce.tar.gz";
      sha256 = "04387gzgl8y555b3lkz9aiw9xsldfg4zmzp930m62qw8zbrvrshd";
    }
  12. Use NUR packages in a Flake-based devshell

    main

    To add a single package from NUR to a devShell in a flake.nix, include NUR in your inputs and apply its overlay to your pkgs instance.

    {
      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
        flake-utils.url = "github:numtide/flake-utils";
        nur = {
          url = "github:nix-community/NUR";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
    
      outputs = { self, nixpkgs, flake-utils, nur }: 
        flake-utils.lib.eachDefaultSystem (system: 
          let
            pkgs = import nixpkgs {
              inherit system;
              overlays = [ nur.overlays.default ];
            };
          in
          {
            devShells.default = pkgs.mkShell {
              packages = [ pkgs.nur.repos.mic92.hello-nur ];
            };
          }
        );
    }