Packages exposed by module

Hi,

I reach out to you to learn about best practices in creating NixOS modules and packages.

I wonder how I should structure the code to create a module, say for a service, and some “tools package” for it, say some shell commands to interact with the service. Focus is on how to expose those tools, in order to use them in other parts of the config. (The basic structure of modules and packages can be left out of focus I think.)

My first approach was this module:

{
  # the usual
} :
let
  tools = ... # an attrset of shell apps
in
{
  options = {
    mymod.enable = ... # the usual
    mymod.tools = ... # defaults to the above `tools`
  };

  config = lib.mkIf config.mymod.enable {
    # service definition goes here
  };
}

With this, one can declaratively use config.mymod.tools to access the various tools by name (ie. by attrset key).

One downside is that this allows to override the tools, which is not intended. Also, the default of an option does not seem the right place to expose those packages.

Should I, and how should I, refactor to be more aligned with the usual best practices (“be idiomatic”)?

Thanks all in advance for some input and food 4 thought!
:slight_smile:

You can set readOnly = true; if you don’t want the default value to be overrideable, if I understood your question correctly.

I could build with the readOnly = true addition. Did not know this–thank you!



Anyways, I’m still wondering if/how such a module should be a folder (instead of one file containing everything) and that folder also contains e.g. an additional pkgs folder that exposes the “tools”. Would that be considered clean NixOS modularization? If not, what’s your recommended file/folder structure for this? Thanks for any thoughts :slight_smile: