Very generally, a Nixpkgs package is just a derivation that adheres to some (for now conventionally) standardised output structure. For example:
- If a package has a
/bindirectory, its contents should be executable files. This standard is used to buildPATHin various contexts (nix-shell, NixOS, nix-env, etc.). This is the most common interpretation of a package. - If a package has a
/libdirectory, it contains library files that can be linked to, made use of by e.g.buildInputsand to buildLD_LIbRARY_PATH. There’s a lot of packages that only have a/libdirectory and no/bin, e.g.pkgs.libpng - If a package has a
/lib/python3/site-packagesdirectory, it contains Python libraries, which e.g.propagatedBuildInputsfrombuildPythonApplicationmakes use of, but can also be used to buildPYTHON_PATH - If a package has a
/lib/systemddirectory, it contains systemd units, which is used by e.g. NixOS, but can also be used by other systemd distros. - If a package has a
/share/fontsdirectory, it contains fonts, which is made use of by e.g. thefonts.packagesoption. - etc.
NixOS also has a very generic way for composing many packages exposing such directories into a single location (this can be understood as “installing”): environment.systemPackages and environment.pathsToLink, getting composed into /run/current-system/sw.
So it’s definitely not a problem to put derivations into Nixpkgs that don’t contain binaries. Whether a derivation is a good fit for Nixpkgs depends on entirely orthogonal factors, which are documented to a degree here.