How to: Create your own modules

After building and installing your own software, you might find it convenient to add it to your personal module tree.

There are three basic steps:

  1. Create module directory tree
  2. Add module directory tree to $MODULEPATH
  3. Create module file from template

Read below for more details on each step.

1. Create module directory tree

You’ll need to set up a directory tree where all your module files will be saved to. You can place the root of the directory tree anywhere but we’ll use $MODULE_ROOT for this document.

You can look at /spack/apps/lmod/linux-centos7-x86_64/ to get an idea of the structure we use at CARC.

Since CARC manages so many applications we have our module tree seprated by compiler used, MPI library, and BLAS library. This is probably excessive for most users so you might want a structure like:

In this example there are 2 directories under $MODULE_ROOT, software1 and software2. Each of these software directories has at least 1 module file written in Lua (don’t worry, there’s a template you can use below).

2. Add module directory tree to $MODULEPATH

After creating the directory tree you can add it to your $MODULEPATH by running the command

module use $MODULE_ROOT

It’s best to put this in your ~/.bashrc so you don’t need to run it every time you log in.

3. Create module file from template

Essentially module files are lua scripts that set environment and “PATH-like” variables. They can also provide information on how software was built and load prerequisite modules.

For an in-depth guide on writing module files, look at

To get started quickly you can modify the template below.

-- -*- lua -*-
-- Template module file
-- Put comments here

whatis([[Name : software_name]])
whatis([[Version : version_here]])
whatis([[Target : x86_64]])
whatis([[Short description : Describe your software here]])
whatis([[Configure options : Describe build options here]])

help([[ Put a long description here ]])

setenv("SOFTWARE_ROOT", "Install prefix here")

prepend_path("PATH", "Abosulte path here", ":")
prepend_path("MANPATH", "Usually ${SOFTWARE_ROOT}/share/man", ":")
prepend_path("LD_LIBRARY_PATH", "Usually ${SOFTWARE_ROOT}/lib", ":")

For example, if you had a Python 3.7.6 installation in /project/ttrojan_412/software/python/3.7.6 you might use a module file like this:

-- -*- lua -*-
-- Python 3.7.6 install
-- 2020-09-18

whatis([[Name : Python]])
whatis([[Version : 3.7.6]])
whatis([[Target : x86_64]])
whatis([[Short description : Python programming language]])
whatis([[Configure options : --enable-shared --prefix=/project/ttrojan_412/software/python/3.7.6]])

help([[ My own build of python]])

setenv("PYTHON_ROOT", "/project/ttrojan_412/software/python/3.7.6")

prepend_path("PATH", "/project/ttrojan_412/software/python/3.7.6/bin", ":")
prepend_path("MANPATH", "/project/ttrojan_412/software/python/3.7.6/share/man", ":")
prepend_path("LD_LIBRARY_PATH", "/project/ttrojan_412/software/python/3.7.6/lib", ":")

If you’d like to set any environment variables like $PYTHON_ROOT, use a command like


For “PATH-like” variables like $PATH, $MANPATH, or $LD_LIBRARY_PATH, use the command

prepend_path(VARIABLE,"/path/of/interest", ":")

Note that : indicates you want each directory in the “PATH-like” variable separated with : characters.

If your application requires other software to work properly, you may want your module file to load other modules. You can do so by including a line like


Finally, make sure to give the file a meaningful name, usually the version of the software you’ve built. This is what shows up when you run the module avail command.