It should be identical to the upstream package name.
It must not contain uppercase letters.
Example: Use "mplayer" instead of "MPlayer"
Media Preservation Frontend Checker has two upstream package names:
Its long name is “Media Preservation Frontend Checker”. According to the above rules, I should change that name to "media preservation frontend checker" if I’m going to use it as a pname value.
Its short name is “MPF.Check”. According to the above rules, I should change that name to "mpf.check" if I’m going to use it as a pname value.
Both of those potential pname values look wrong to me. The first one contains spaces, and the second one contains a dot. The rules for pname attributes don’t disallow spaces or dots, but I feel like that might have been an accidental omission.
Are spaces and dots supposed to be allowed in pname values?
Could you elaborate? What do you mean by “the implicit rules”?
I agree, it would be easy to confuse them with nested set notation. That’s why I was surprised when I didn’t see any rules that prohibited the inclusion of dots in the pnames and attribute names of packages in Nixpkgs. Perhaps a rule that prohibits dots should be added.
Any builder uses builtins.derivation under the hood eventually. It is impossible to create a derivation without it, so we inherit all rules its usage implies. One of the rules is, that a derivation name must not contain spaces.
I agree that all all builders must use builtins.derivation (or builtins.derivationStrict, I guess) under the hood because that’s the only way to create a derivation, and I also agree that the value of the name attribute that gets passed to builtins.derivation must not contain spaces. I can verify that that’s the case by trying to build this Nix expression:
# This file is dedicated to the public domain using 🅭🄍1.0:
# <https://creativecommons.org/publicdomain/zero/1.0>.
let
# At the moment, this commit is the tip of the nixos-unstable branch.
nixpkgsCommit = "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685";
nixpkgsDirectory = builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsCommit}.tar.gz";
sha256 = "0y28hhfxx1w06qrvwdxiwpm7rzplmsm255y49nkn40y82vn38x0g";
};
pkgs = import nixpkgsDirectory { };
inherit (pkgs.lib.strings) escapeShellArg escapeNixString;
nameWithSpaces = builtins.derivation {
name = "name with spaces";
system = pkgs.stdenv.buildPlatform.system;
builder = pkgs.lib.meta.getExe pkgs.bash;
args = [
"-c"
"printf 'The value of name is %s.\\n' ${escapeShellArg (escapeNixString nameWithSpaces.name)} > \"$out\""
];
};
in
nameWithSpaces
When I try to build that Nix expression, I get an error that clearly indicates that spaces are not allowed in name values:
$ nix-build 'name with spaces.nix'
error:
… while calling the 'derivationStrict' builtin
at <nix/derivation-internal.nix>:37:12:
36|
37| strict = derivationStrict drvAttrs;
| ^
38|
… while evaluating derivation 'name with spaces'
whose name attribute is located at /home/jayman/Documents/Home/local/tmp/name with spaces.nix:13:5
error: invalid derivation name: name 'name with spaces' contains illegal character ' '. Please pass a different 'name'.
$
That being said, I don’t think that the rules for pname values inherit all of the rules for name values. I was able to verify that pname values can contain spaces by building this Nix expression:
# This file is dedicated to the public domain using 🅭🄍1.0:
# <https://creativecommons.org/publicdomain/zero/1.0>.
let
# At the moment, this commit is the tip of the nixos-unstable branch.
nixpkgsCommit = "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685";
nixpkgsDirectory = builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsCommit}.tar.gz";
sha256 = "0y28hhfxx1w06qrvwdxiwpm7rzplmsm255y49nkn40y82vn38x0g";
};
pkgs = import nixpkgsDirectory { };
inherit (pkgs.lib.strings) escapeShellArg escapeNixString;
in
pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "pname with spaces";
version = "0-unstable-2026-03-30";
dontUnpack = true;
buildPhase = ''
printf 'The value of pname is %s.\n' ${escapeShellArg (escapeNixString finalAttrs.pname)} > "$out"
'';
})
When I build that Nix expression, here’s what happens:
$ nix-build 'pname with spaces.nix'
/nix/store/y4s06kaipza4mny8jwl9nvv7m2g5ki4c-pname-with-spaces-0-unstable-2026-03-30
$ cat result
The value of pname is "pname with spaces".
$
From you perspective, what is the difference between guidelines and rules?
Yeah, there are probably a bunch of different corner cases where it does make sense to include dots in pname values. If a guideline about dots gets added, it should probably use an RFC 2119 should instead of an RFC 2119 must.
Interesting, this normalisation/slugification must be new… I was not aware that this happens, last time I tried this (mostly by accident) is years ago…
If the pname starts with a digit, the attribute name should be prefixed with an underscore. Otherwise the attribute name should not be prefixed with an underscore.
Example: The corresponding attribute name for 0ad should be _0ad.
New attribute names should be the same as the value in pname.
If there are multiple versions of a package, this should be reflected in the attribute names in all-packages.nix.
Example: json-c_0_9 and json-c_0_11
If there is an obvious “default” version, make an extra attribute.
Example: json-c = json-c_0_9;
This answers your questions: since new packages should have pname equal to their attribute name modulo starting with a digit or not, and attribute names must be valid identifiers, pname should match [A-Za-z0-9_][A-Za-z0-9_'-]*. A preference for hyphenation over camel case is stated explicitly, and a preference for hyphenation over underscores is implied by the versioned example and common practice. (Single quotes aren’t explicitly addressed anywhere, but would be pretty awful for CLI UX and pkgs/by-name directory names, so presumably nobody has ever thought about wanting to try using them in the first place.)
Therefore the characters you are unsure about are explicitly advised against for new packages and your options look like mpf-check, mpfcheck, media-preservation-frontend-checker. I’d prefer the first one.
I prefer your interpretation, but attribute names have to be valid names, not valid identifiers (according to the page you link), which does include arbitrary string literals.
I agree that in general attribute names can be arbitrary string literals. I can verify that that is the case by evaluating this Nix expression:
{
"attribute name that contains spaces" = null;
}
That Nix expression validates successfully on my system which indicates that you are indeed right that attribute names can be arbitrary string literals. That being said, I think that there are extra guidelines that apply to the attribute names of packages in Nixpkgs that don’t necessarily apply to other attribute names. The part of the guidelines that emily quoted says:
What makes you say that it must be a valid name instead of a valid identifier?
I created a Nixpkgs pull request that was inspired by the discussions in this thread. The goal of the pull request is to make Nixpkgs’s package naming guidelines simpler and easier to follow so that questions like this one don’t crop up in the future.