Skip to content

Using Modules

Nilla projects are built on Aux Lib’s module system. This means that we define our project in individual chunks called modules.

What is a Module?

A module two important parts:

  • options: A place to declare available options that can be used in the project.
  • config: A place to define the project’s configuration.

More directly, a module typically specifies a config value with settings to apply to your project. Sometimes, a module will also create new options that can be used in the project, but this is not always necessary.

Defining a Module

A module can be specified in 3 different ways. Let’s go through them.

Attribute Set Module

An attribute set is a valid Aux Lib module. This is the simplest way to define a module, but due to that simplicity it lacks the ability to refer to other parts of the project configuration.

my-module.nix
{
options = {
# Declare your options here...
};
config = {
# Define your project configuration here...
};
}

Function Module

More useful than an attribute set, a function module can refer to other parts of the project via its arguments. The return value of the function is an attribute set just like the one we saw above.

my-module.nix
# Aux Lib, Project configuration, and Project options are available as arguments.
# To refer to parts of the project configuration, you can reference `config`.
{ lib, config, options }:
# We return our module definition with its options and config.
{
options = {
# Declare your options here...
};
config = {
# Define your project configuration here...
};
}

Path Module

Since it is so common to separate modules into their own files, modules can be specified as a path to the file containing the module definition. Aux Lib will then import and use your module.

./my-module.nix

Including Modules

To start using modules in your project, you can use the includes module attribute to specify additional modules that Aux Lib should include in your project.

nilla.nix
let
pins = import ./npins;
nilla = import pins.nilla;
in
nilla.create {
includes = [
# Add any of the modules you want to use here.
# For example, we can add the module defined in `my-module.nix` via a path.
./my-module.nix
# Or we can define a module inline.
{ config = { }; }
];
}

Creating Options

You can create your own options in a module by defining options. A consumer of your module can then set these options and benefit from their application. Let’s take a look at how to create a simple option that allows us to set a message in our project configuration.

nilla.nix
{ lib, config }:
let
# If you want, you can access the value of the message option from `config`. This is
# the final value that is set in the project.
cfg = config.message;
in
{
options = {
# Create our new option.
message = lib.options.create {
# Set a description so users know what this option is for.
description = "The message for this project.";
# Set the type of the option. This is used to validate the input whenever this option
# is set. If the input is not valid then an error will be shown.
type = lib.types.string;
# Set the default value for this option.
default.value = "Hello, World!";
};
};
config = {
# Now any module can set `message`!
message = "This is my special message!";
};
}