diff --git a/.hunspell.en.dic b/.hunspell.en.dic
index cd0ef5637..7482eb4aa 100644
--- a/.hunspell.en.dic
+++ b/.hunspell.en.dic
@@ -1605,3 +1605,15 @@ TOOL2
sphinxext
opengraph
PNG
+HPSFCon
+pu
+xargs
+jq
+PyPI
+gui
+spack
+mpivars
+cuda
+lindex
+defineModStartNbProc
+isIcase
diff --git a/NEWS.rst b/NEWS.rst
index 24c149529..b30b07019 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -248,6 +248,9 @@ Modules 5.7.0 (not yet released)
:ref:`CONTRIBUTING`: AI agents must never add their own ``Signed-off-by:``
trailer and their involvement must be disclosed with an ``Assisted-by:``
trailer.
+* Doc: add the :ref:`user-guide` document that explains a selection of
+ useful but lesser known features through practical examples and common
+ use cases.
.. _5.6 release notes:
diff --git a/doc/source/index.rst b/doc/source/index.rst
index fd404cfe4..15ef84fc5 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -184,6 +184,7 @@ or (at your option) any later version (`GPL-2.0-or-later`).
INSTALL-win
MIGRATING
NEWS
+ user-guide
FAQ
changes
other-implementations
diff --git a/doc/source/latex_index.rst b/doc/source/latex_index.rst
index 91f241e37..54208eb2c 100644
--- a/doc/source/latex_index.rst
+++ b/doc/source/latex_index.rst
@@ -18,4 +18,5 @@ Introduction
.. include:: envml.rst
.. include:: MIGRATING.rst
.. include:: NEWS.rst
+.. include:: user-guide.rst
.. include:: changes.rst
diff --git a/doc/source/modulefile.rst b/doc/source/modulefile.rst
index 815b712f8..49194f469 100644
--- a/doc/source/modulefile.rst
+++ b/doc/source/modulefile.rst
@@ -2100,6 +2100,8 @@ or terse reporting of these sub-commands: :mconfig:`avail_output`,
:mconfig:`list_terse_output`, :mconfig:`spider_output`,
:mconfig:`spider_terse_output`.
+.. _advanced_module_version_specifiers:
+
Advanced module version specifiers
----------------------------------
diff --git a/doc/source/user-guide.rst b/doc/source/user-guide.rst
new file mode 100644
index 000000000..617294bad
--- /dev/null
+++ b/doc/source/user-guide.rst
@@ -0,0 +1,1135 @@
+.. _user-guide:
+
+Lesser known features
+=====================
+
+Environment Modules provides many capabilities beyond the commonly used
+:command:`module` :subcmd:`load` command. Some features are lesser known, despite being very
+useful for users, modulefile developers, and site administrators.
+
+This document gathers and explains a selection of these features through
+practical examples and common use cases.
+
+It originates from the presentation *Beyond "module load": Exploring the
+Capabilities of Environment Modules* given at `HPSFCon 2026
+`_. Original slides and video
+demonstrations can be found on the `event session page
+`_.
+
+Short command names
+-------------------
+
+Most Modules sub-commands can be abbreviated. The :command:`ml` command also
+provides a shorter alternative interface for common operations.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Standard command
+ - Short form
+
+ * - ``module ``
+ - ``ml ``
+
+ * - ``module avail``
+ - ``module av``
+
+ * - ``module purge``
+ - ``module pu``
+
+ * - ``module list``
+ - ``ml``
+
+ * - ``module load ``
+ - ``ml ``
+
+ * - ``module unload ``
+ - ``ml -``
+
+Display/Parsing
+---------------
+
+``--output=LIST``
+^^^^^^^^^^^^^^^^^
+
+The :option:`--output`, or :option:`-o`, option customizes the information
+displayed by Modules commands.
+
+It is supported by :command:`module` :subcmd:`avail`, :subcmd:`list`, and
+:subcmd:`spider` sub-commands.
+
+By default, these commands display additional formatting elements such as
+modulepaths, tags, default markers, or variant information. With
+:option:`--output`, it is possible to restrict the displayed information to
+only the needed fields.
+
+This option is especially useful when parsing command output in shell scripts,
+Python programs, or monitoring tools.
+
+For example, with the following available modulefiles:
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8
+
+When *LIST* is set to an empty value, only module names are displayed:
+
+.. parsed-literal::
+
+ :ps:`$` module avail -o ''
+ gcc/8.3 gcc/11.1 gcc/14.0 openmpi/5.0.8
+
+The output format is defined as a colon-separated list of elements. Supported
+elements are documented in the corresponding sub-command manual pages.
+
+*LIST* may also be prefixed by ``+`` or ``-`` to respectively append elements
+to or subtract them from the currently configured value. For example, report
+the variants declared by each modulefile in addition to the default output:
+
+.. parsed-literal::
+
+ :ps:`$` module avail -o +variant
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8\ :sgrse:`{`:sgrva:`cuda=on`:sgrse:`,`\ :sgrva:`off`:sgrse:`}`
+
+This feature helps avoid fragile text parsing pipelines.
+
+Instead of parsing formatted output:
+
+.. code-block:: bash
+
+ modules_list=$(module avail | grep -v '^---' \
+ | sed 's/(default)//g' | head -n -2 | xargs)
+
+A simpler and more robust approach is:
+
+.. code-block:: bash
+
+ modules_list=$(module avail -o '')
+
+``spider``
+^^^^^^^^^^
+
+The :command:`module` :subcmd:`spider` sub-command lists all available
+modulefiles found in enabled modulepaths, including modulepaths recursively
+added by modulefiles.
+
+Unlike :subcmd:`avail`, :subcmd:`spider` explores the full dependency tree
+created by :mfcmd:`module use`, :mfcmd:`append-path`, or
+:mfcmd:`prepend-path` instructions.
+
+This command is especially useful with hierarchical module layouts, where some
+modulefiles only become visible after loading compiler or MPI dependencies.
+
+The :subcmd:`spider` sub-command accepts the same display and formatting
+options as :subcmd:`avail`, including :option:`--output`,
+:option:`--latest`, :option:`--default`, :option:`--json`,
+:option:`--indepth`, and :option:`--no-indepth`.
+
+For example, in a hierarchical environment:
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles/common` ------------------
+ gcc/14.0 intel/25.0
+
+Only compiler modules are initially visible.
+
+The :subcmd:`spider` sub-command reveals additional modules together with
+their dependency path:
+
+.. parsed-literal::
+
+ :ps:`$` module spider
+ ------------------- :sgrmp:`/usr/share/modulefiles/common` ------------------
+ gcc/14.0 intel/25.0
+
+
+ ---------- :sgrmp:`/usr/share/modulefiles/intel` (via intel/25.0) -----------
+ intelmpi/25.0
+
+ ------------ :sgrmp:`/usr/share/modulefiles/gcc` (via gcc/14.0) -------------
+ openmpi/5.0.8
+
+
+This output indicates which modules must be loaded before these MPI stacks
+become available.
+
+Modules caches are automatically used by :subcmd:`spider` when configured,
+which significantly improves search performance on large installations.
+
+``--latest`` and ``--default``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :option:`--latest`, or :option:`-L`, and :option:`--default`, or
+:option:`-d`, options restrict the output of the :command:`module`
+:subcmd:`avail` and :subcmd:`spider` sub-commands.
+
+For example, with the following available modulefiles:
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 intel/24.0 intel/25.0
+
+The :option:`--latest` option displays only the highest numerically sorted
+version of each module name.
+
+.. parsed-literal::
+
+ :ps:`$` module avail --latest
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/14.0 intel/25.0
+
+The :option:`--default` option displays only the default version of each
+module name. This version is either explicitly defined (as here for ``gcc``)
+or implicitly the highest one (as for ``intel``).
+
+.. parsed-literal::
+
+ :ps:`$` module avail --default
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ :sgrde:`gcc/11.1` intel/25.0
+
+These options may also be combined with other display options such as
+:option:`--output` or :option:`--json`.
+
+``--indepth`` and ``--no-indepth``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :option:`--indepth` and :option:`--no-indepth` options control how the
+:command:`module` :subcmd:`avail` and :subcmd:`spider` sub-commands search
+for matching modulefiles.
+
+By default, Modules searches recursively and returns all matching
+modulefiles. This behavior is equivalent to :option:`--indepth` and
+can be configured with :command:`module` :subcmd:`config` :mconfig:`avail_indepth`
+and :mconfig:`spider_indepth`.
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ intel/24.0 intel/25.0 gcc/8.3 gcc/11.1 gcc/14.0
+
+The :option:`--no-indepth` option limits results to the depth level
+expressed by the search query. Modulefiles contained in matching directories
+are not displayed.
+
+.. parsed-literal::
+
+ :ps:`$` module avail --no-indepth
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ :sgrdi:`intel`/ :sgrdi:`gcc`/
+
+``--json``
+^^^^^^^^^^
+
+The :option:`--json`, or :option:`-j`, option displays command results in
+JSON format.
+
+It is supported by the :command:`module` :subcmd:`avail`, :subcmd:`list`,
+:subcmd:`savelist`, :subcmd:`search`, :subcmd:`spider`,
+:subcmd:`stashlist`, and :subcmd:`whatis` sub-commands.
+
+JSON output is intended for machine consumption and can be processed directly
+by tools such as ``jq`` or Python scripts.
+
+.. parsed-literal::
+
+ :ps:`$` module avail -j | jq .
+ {
+ "/usr/share/modulefiles": {
+ "gcc/14.0": {
+ "name": "gcc/14.0",
+ "type": "modulefile",
+ "symbols": [],
+ "tags": [],
+ "pathname": "/usr/share/modulefiles/gcc/14.0",
+ "via": ""
+ },
+ ...
+ }
+
+The JSON format is also useful for monitoring, reporting, and integration
+with external tools.
+
+Manipulating the environment for users
+--------------------------------------
+
+Collections
+^^^^^^^^^^^
+
+Collections save and restore sets of loaded modules.
+
+They provide a convenient way to switch between software environments without
+having to manually load and unload each module.
+
+Collections are managed through several :command:`module` sub-commands:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Sub-command
+ - Description
+
+ * - :subcmd:`save` [collection]
+ - Save the current module environment to a collection.
+
+ * - :subcmd:`restore` [collection]
+ - Restore a collection or collection file.
+
+ * - :subcmd:`savelist`
+ - List saved collections.
+
+ * - :subcmd:`saverm` [collection]
+ - Remove a saved collection.
+
+ * - :subcmd:`saveshow` [collection]
+ - Display information about a collection.
+
+ * - :subcmd:`is-saved` [collection]
+ - Test whether one or more collections exist.
+
+Collections are stored under the user collection directory, usually
+:file:`$HOME/.module`.
+
+The :envvar:`MODULES_COLLECTION_TARGET` environment variable may be defined
+to append a suffix to collection names. This feature is particularly useful
+on systems sharing a common home directory across multiple clusters.
+
+.. parsed-literal::
+
+ :ps:`$` module save
+ :ps:`$` module purge
+ :ps:`$` module restore
+
+``stash`` commands
+^^^^^^^^^^^^^^^^^^
+
+Stash collections temporarily save the current module environment and make it
+easy to switch to another environment.
+
+This feature is similar to the :command:`git stash` workflow: save the current
+state, perform other work, then restore the original environment later.
+
+Stash collections are managed through several :command:`module`
+sub-commands:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Sub-command
+ - Description
+
+ * - :subcmd:`stash`
+ - Save the current environment and reset it.
+
+ * - :subcmd:`stashpop`
+ - Restore and remove a stash collection.
+
+ * - :subcmd:`stashrm`
+ - Remove a stash collection.
+
+ * - :subcmd:`stashshow`
+ - Display information about a stash collection.
+
+ * - :subcmd:`stashclear`
+ - Remove all stash collections.
+
+ * - :subcmd:`stashlist`
+ - List stash collections.
+
+Save the current environment:
+
+.. parsed-literal::
+
+ :ps:`$` module stash
+
+Load a different software stack:
+
+.. parsed-literal::
+
+ :ps:`$` module purge
+ :ps:`$` module load ...
+
+Restore the original environment:
+
+.. parsed-literal::
+
+ :ps:`$` module stashpop
+
+Unlike regular collections, stash collections are intended to be short-lived
+and are automatically removed when restored with
+:subcmd:`stashpop`.
+
+``mogui``
+^^^^^^^^^
+
+``mogui`` provides a graphical interface to browse available modules and
+manage collections.
+
+It offers an alternative to the command line and can be useful for new users
+discovering a software stack or for users who prefer an interactive
+interface.
+
+Any environment change made from the GUI, such as loading modules or
+restoring collections, is applied back to the shell session that launched
+the application.
+
+The project is available on GitHub:
+`cea-hpc/mogui `_. It can be installed
+from PyPI with :command:`pip` or from Spack.
+
+.. parsed-literal::
+
+ :ps:`$` pip install modules-gui
+
+or:
+
+.. parsed-literal::
+
+ :ps:`$` spack install py-modules-gui
+
+Then start the graphical interface:
+
+.. parsed-literal::
+
+ :ps:`$` mogui
+
+.. image:: https://raw.githubusercontent.com/cea-hpc/mogui/main/doc/sneak_peek.gif
+ :alt: mogui graphical interface
+ :align: center
+
+``envml``
+^^^^^^^^^
+
+The :ref:`envml(1)` command executes a command in a specific module
+environment.
+
+It applies the requested module actions, executes the command, then restores
+the original environment. As a result, the current shell session remains
+unchanged.
+
+This feature is particularly useful in scripts, tests, and automation
+workflows where commands must be executed in a controlled software
+environment.
+
+Supported module actions include:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 35 65
+
+ * - Action
+ - Description
+
+ * - ``purge``
+ - Purge all loaded modules.
+
+ * - ``restore=``
+ - Restore a saved collection.
+
+ * - ``unload=``
+ - Unload one or more modules.
+
+ * - ``switch=&``
+ - Switch from one module to another.
+
+ * - ``load=``
+ - Load one or more modules.
+
+ * - ````
+ - Shorthand form of ``load=``.
+
+Multiple actions may be chained with the ``:`` separator. When specifying
+multiple modules for a single action, use the ``&`` separator. In some
+shells, such as Bash, the ``&`` character must be escaped or quoted.
+
+For example, execute a command in a clean environment:
+
+.. parsed-literal::
+
+ :ps:`$` envml purge -- gcc hello.c
+
+The :ref:`envml(1)` command can simplify scripts by replacing sequences of
+module operations with a single command.
+
+Instead of:
+
+.. code-block:: bash
+
+ #!/bin/bash
+ module purge
+ module load gcc
+ gcc hello.c
+
+One can write:
+
+.. code-block:: bash
+
+ #!/bin/bash
+ envml purge:gcc -- gcc hello.c
+
+Protected environment variables
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :mconfig:`protected_envvars` configuration option prevents Modules from
+modifying selected environment variables. Multiple variables may be specified
+using the ``:`` separator.
+
+This feature is useful to protect critical environment settings from
+unintended changes.
+
+When a modulefile attempts to modify a protected variable, Modules ignores
+the modification and emits a warning.
+
+.. parsed-literal::
+
+ :ps:`$` module config protected_envvars LD_PRELOAD
+ :ps:`$` module load intel
+ Loading :sgrhi:`intel/25.0`
+ :sgrwa:`WARNING`: Modification of protected environment variable LD_PRELOAD ignored
+
+Developing and configuring modulefiles
+--------------------------------------
+
+``module edit``
+^^^^^^^^^^^^^^^
+
+The :command:`module` :subcmd:`edit` sub-command opens a modulefile in the
+configured text editor (cf. :subcmd:`config` :mconfig:`editor`).
+
+Instead of manually locating a modulefile:
+
+.. parsed-literal::
+
+ :ps:`$` vi $(module path appA)
+
+One can directly edit it with:
+
+.. parsed-literal::
+
+ :ps:`$` module edit appA
+
+``module lint``
+^^^^^^^^^^^^^^^
+
+The :command:`module` :subcmd:`lint` sub-command analyzes modulefiles and
+reports potential issues.
+
+It relies on the Nagelfar Tcl syntax checker to detect syntax errors and
+common mistakes.
+
+Analyze a specific modulefile:
+
+.. parsed-literal::
+
+ :ps:`$` module lint appA
+
+Reported issues may include:
+
+* Unknown variables
+* Unknown commands
+* Invalid command arguments
+* Tcl syntax errors
+
+``source-sh``
+^^^^^^^^^^^^^
+
+The :mfcmd:`source-sh` modulefile command evaluates a shell script and tracks
+the environment changes it performs.
+
+The detected changes are translated into modulefile actions, making it
+possible to load and unload shell-based environments through Modules.
+
+It is particularly useful to integrate software distributions that provide
+environment setup scripts such as ``setup-env.sh``, ``mpivars.sh``, or
+similar rc-provided files.
+
+For example:
+
+.. code-block:: tcl
+
+ #%Module
+
+ source-sh bash /opt/spack/share/spack/setup-env.sh
+
+``sh-to-mod``
+^^^^^^^^^^^^^
+
+The :command:`module` :subcmd:`sh-to-mod` sub-command evaluates a shell script
+and reports the resulting environment changes as modulefile commands.
+
+It can be used to convert existing shell initialization scripts into
+modulefiles.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module sh-to-mod bash setup-env.sh > setup-env.mod
+
+.. tip::
+
+ Use :subcmd:`sh-to-mod` when you want to generate and maintain a regular
+ modulefile from an existing shell script.
+
+``mod-to-sh``
+^^^^^^^^^^^^^
+
+The :command:`module` :subcmd:`mod-to-sh` sub-command evaluates one or more
+modulefiles and reports the resulting environment changes as shell code.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module mod-to-sh bash appA > setup-env.sh
+
+.. tip::
+
+ The :subcmd:`mod-to-sh` sub-command can be seen as the reverse operation of
+ :subcmd:`sh-to-mod`.
+
+``prereq``
+^^^^^^^^^^
+
+The :mfcmd:`prereq` modulefile command declares one or more modules as a
+requirement of the current modulefile. When the automated module handling
+mode is enabled (see :mconfig:`auto_handling`), which is the default, a
+requirement is automatically loaded if not yet present in the user
+environment.
+
+Requirements are sometimes expressed with a condition block:
+
+.. code-block:: tcl
+
+ if { ! [ is-loaded appA ] } {
+ module load appA
+ }
+
+This must be avoided: when ``appA`` is already loaded, the condition is
+false and no requirement rule is defined, so Modules is not aware that the
+current module depends on ``appA``.
+
+Declare the requirement unconditionally instead:
+
+.. code-block:: tcl
+
+ prereq appA
+
+Loading a module declaring this requirement (here ``appB``) automatically
+loads the required module when missing:
+
+.. parsed-literal::
+
+ :ps:`$` module load appB
+ Loading :sgrhi:`appB`
+ :sgrin:`Loading requirement`: appA
+
+When automated module handling is disabled, a missing requirement is not
+automatically loaded: an error is reported and the modulefile load fails.
+
+The :mfcmd:`module load` modulefile command equally declares a
+requirement rule, and it loads the missing required module even when
+automated module handling is disabled. The two commands also differ when
+several modules are specified: :mfcmd:`module load` loads them all
+(logical AND) whereas :mfcmd:`prereq` requires only one of them (logical
+OR). Multiple :mfcmd:`prereq` commands act as a logical AND.
+
+``conflict``
+^^^^^^^^^^^^
+
+The :mfcmd:`conflict` modulefile command declares one or more modules that
+cannot be loaded together with the current modulefile.
+
+Instead of manually checking for incompatible modules:
+
+.. code-block:: tcl
+
+ if { [ is-loaded appB ] } {
+ puts stderr "ERROR: appB conflicts with appA!"
+ exit 1
+ }
+
+Declare the conflict with:
+
+.. code-block:: tcl
+
+ conflict appB
+
+When the :mconfig:`conflict_unload` configuration option is enabled in
+addition to the automated module handling mode (see :mconfig:`auto_handling`),
+loading a module automatically unloads the conflicting modules found in the
+user environment:
+
+.. parsed-literal::
+
+ :ps:`$` module load appA
+ Loading :sgrhi:`appA`
+ :sgrin:`Unloading conflict`: appB
+
+When these options are disabled, an error is reported instead and the
+modulefile load fails.
+
+A modulefile declaring a conflict on its own module name defines a
+*reflexive conflict*: only one version of this module can then be loaded at
+a time.
+
+.. code-block:: tcl
+
+ conflict appA
+
+.. parsed-literal::
+
+ :ps:`$` module load appA/2.0
+ Loading :sgrhi:`appA/2.0`
+ :sgrin:`Unloading conflict`: appA/1.0
+
+.. tip::
+
+ When only one module should be loaded at a time for any given module
+ name, enable the :mconfig:`unique_name_loaded` configuration option
+ instead of declaring a reflexive conflict in every modulefile. As this
+ option applies to all existing modules, every module name must follow
+ this rule. It is generally the case when only *application* modules are
+ provided, but may not be if application configurations are also handled
+ through modulefiles.
+
+``variant``
+^^^^^^^^^^^
+
+The :mfcmd:`variant` modulefile command declares variants and their accepted
+values.
+
+This command is only available inside modulefiles.
+
+Variants allow users to customize the behavior of a modulefile at load time.
+They follow the same syntax as Spack variants.
+
+Boolean variants are enabled with ``+`` and disabled with ``~``:
+
+.. code-block:: tcl
+
+ #%Module
+ variant --boolean cuda
+
+.. parsed-literal::
+
+ :ps:`$` module load openmpi +cuda
+
+Variants with multiple values are declared by listing the accepted values:
+
+.. code-block:: tcl
+
+ #%Module
+ variant compiler gcc intel
+
+And selected with the ``=`` syntax:
+
+.. parsed-literal::
+
+ :ps:`$` module load openmpi compiler=intel
+
+The :mfcmd:`getvariant` modulefile command retrieves the value of a declared
+variant, allowing the modulefile to adapt its behavior.
+
+For example:
+
+.. code-block:: tcl
+
+ switch -- [getvariant compiler] {
+ gcc {
+ prereq gcc
+ }
+ intel {
+ prereq intel
+ }
+ }
+
+Configuration option :mconfig:`variant_shortcut` defines shortcut characters
+for variants.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module config variant_shortcut compiler=%
+
+This allows users to write:
+
+.. parsed-literal::
+
+ :ps:`$` module load openmpi %gcc
+
+Advanced manipulations
+----------------------
+
+Advanced module version specifiers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:ref:`advanced_module_version_specifiers` provide a concise way to select modulefiles based on
+their version or declared variants. They can be used with several
+:command:`module` sub-commands, including :subcmd:`avail`,
+:subcmd:`spider`, :subcmd:`load`, and :subcmd:`switch`.
+
+Version specifications use the ``@`` character:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Specification
+ - Description
+
+ * - ``module avail cuda@default``
+ - Select the default version.
+
+ * - ``module avail cuda@latest``
+ - Select the latest version.
+
+ * - ``module avail cuda@12:``
+ - Select versions greater than or equal to ``12``.
+
+ * - ``module avail cuda@:12``
+ - Select versions lower than or equal to ``12``.
+
+ * - ``module avail cuda@12:13``
+ - Select versions between ``12`` and ``13``.
+
+Variant specifications may also be used:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Specification
+ - Description
+
+ * - ``module avail +mpi``
+ - Select modules declaring the ``mpi`` variant.
+
+ * - ``module avail cuda=12``
+ - Select modules where the ``cuda`` variant is set to ``12``.
+
+ * - ``module avail +mpi +cuda``
+ - Select modules matching both variant requirements.
+
+``--timer`` and ``--debug``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :option:`--timer` and :option:`--debug`, or :option:`-D`, options help
+analyze and troubleshoot Modules commands.
+
+They are supported by most :command:`module` sub-commands.
+
+The :option:`--timer` option reports the total execution time of a command.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module avail --timer
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8
+
+ :sgrtr:`TIMER Total execution took 20.045 ms`
+
+The :option:`--debug`, or :option:`-D`, option displays debugging messages
+describing the internal execution of the command.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module avail -D
+ :sgrtr:`DEBUG setState: cmdline set to 'modulecmd.tcl bash avail -D'`
+ :sgrtr:`DEBUG setState: shell set to 'bash'`
+ :sgrtr:`DEBUG setState: subcmd set to 'avail'`
+ :sgrtr:`DEBUG setConf: verbosity set to 'debug'`
+ ...
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8
+
+The :option:`--timer` and :option:`--debug` options may be combined. In this
+case, regular debug messages are replaced by execution time reports for each
+internal procedure call.
+
+.. parsed-literal::
+
+ :ps:`$` module avail --timer -D
+ :sgrtr:`TIMER parseModuleCommandName avail help (0.151 ms)`
+ :sgrtr:`TIMER isIcase (0.088 ms)`
+ :sgrtr:`TIMER defineModStartNbProc 1 (0.060 ms)`
+ ...
+ :sgrtr:`TIMER Total execution took 31.722 ms`
+
+For even more detailed debugging information, use :option:`-DD`.
+
+``.modulerc`` files
+^^^^^^^^^^^^^^^^^^^
+
+A :file:`.modulerc` file contains Tcl code automatically evaluated by
+Modules when encountered during a command execution.
+
+Rc files are used to define module aliases, virtual
+modules, tags, hidden modules, forbidden modules, ...
+
+Several :file:`.modulerc` files may be evaluated during a single
+:command:`module` command.
+
+Depending on the executed sub-command, Modules may evaluate
+:file:`.modulerc` files found in different locations, including:
+
+* :envvar:`MODULERCFILE`
+* :file:`$HOME/.modulerc`
+* Modulepath and modules directories
+
+For example, the following directory hierarchy contains several
+:file:`.modulerc` files:
+
+.. code-block:: text
+
+ /home/user/.modulerc
+ modulefiles/
+ ├── .modulerc
+ ├── app/
+ │ ├── .modulerc
+ │ └── 1.0
+ └── mpi/
+ ├── .modulerc
+ └── openmpi/5.0
+
+Depending on the requested operation, one or more of these files are
+evaluated automatically.
+
+See :ref:`Modulecmd startup` for details on the startup sequence,
+:mconfig:`rcfile` and :mconfig:`ignore_user_rc` to configure the evaluation
+of user rc files, and :sitevar:`modulerc_extra_vars` and
+:sitevar:`modulerc_extra_cmds` to extend :file:`.modulerc` files.
+
+``module-tag``
+^^^^^^^^^^^^^^
+
+The :mfcmd:`module-tag` modulerc command associates one or more tags with
+modulefiles.
+
+This command is only available inside :file:`.modulerc` files.
+
+Tags may be used to provide additional information about modulefiles or to
+modify their behavior.
+
+For example:
+
+.. code-block:: tcl
+
+ module-tag experimental app/2.0
+
+The tag is then reported along the module name in search results:
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ app/1.0 app/2.0 :sgrse:`<`\ experimental\ :sgrse:`>`
+
+Several predefined tags affect the behavior of Modules:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 25 75
+
+ * - Tag
+ - Description
+
+ * - ``keep-loaded``
+ - Prevent automatic unloading when unloading dependent modules.
+
+ * - ``sticky``
+ - Prevent unloading unless :option:`--force` is specified.
+
+ * - ``super-sticky``
+ - Prevent unloading under any circumstances.
+
+For example:
+
+.. code-block:: tcl
+
+ module-tag sticky core
+
+Once loaded, the ``core`` module cannot be unloaded, even with the
+:subcmd:`purge` sub-command. The ``sticky`` tag is rendered with a specific
+background color in the output.
+
+.. parsed-literal::
+
+ :ps:`$` module purge
+ Unloading :sgrshi:`core/1.0`
+ :sgrer:`ERROR`: Unload of sticky module skipped
+ :ps:`$` module list
+ Currently Loaded Modulefiles:
+ 1) :sgrs:`core/1.0`
+
+Sticky modules can help ensure that essential software stacks remain loaded.
+The behavior of :subcmd:`purge` with sticky modules can be configured through
+:mconfig:`sticky_purge`.
+
+``module-hide``
+^^^^^^^^^^^^^^^
+
+The :mfcmd:`module-hide` modulerc command hides modulefiles from module
+searches and selection.
+
+This command is only available inside :file:`.modulerc` files.
+
+A hidden module is excluded from regular searches but may still be selected
+when explicitly referred to by its exact name.
+
+For example:
+
+.. code-block:: tcl
+
+ module-hide app/1.0
+
+Visibility may also be restricted to specific users or groups.
+
+Time-based restrictions can be defined with ``--after`` and ``--before``.
+
+For example:
+
+.. code-block:: tcl
+
+ module-hide --after 2027-01-01 app/1.0
+
+See :mfcmd:`module-hide` for additional visibility options, including **soft**
+and **hard** hiding, as well as **users** and **groups** restrictions.
+
+``module-forbid``
+^^^^^^^^^^^^^^^^^
+
+The :mfcmd:`module-forbid` modulerc command prevents designated modulefiles
+from being loaded.
+
+This command is only available inside :file:`.modulerc` files.
+
+Unlike a hidden module, a forbidden module remains visible in module searches
+but cannot be loaded.
+
+For example:
+
+.. code-block:: tcl
+
+ module-forbid app/1.0
+
+A custom message may be displayed when a user attempts to load a forbidden
+module with the ``--message`` option.
+
+For example:
+
+.. code-block:: tcl
+
+ module-forbid --message {Please use app/2.0 instead} app/1.0
+
+See :mfcmd:`module-forbid` for additional restriction options, including
+custom messages, as well as **after**/**before**, **users** and **groups** restrictions.
+
+``module-virtual``
+^^^^^^^^^^^^^^^^^^
+
+The :mfcmd:`module-virtual` modulerc command associates a virtual module name
+with an existing modulefile.
+
+This command is only available inside :file:`.modulerc` files.
+
+Several virtual modules may refer to the same modulefile, reducing the number
+of files required to define similar modules.
+
+For example:
+
+.. code-block:: text
+
+ modulefiles/app/
+ ├── .common
+ └── .modulerc
+
+The :file:`.modulerc` file may define several virtual versions:
+
+.. code-block:: tcl
+
+ #%Module
+ module-virtual 1.0 .common
+ module-virtual 1.2 .common
+ module-virtual 1.5 .common
+ module-virtual 2.0 .common
+
+.. parsed-literal::
+
+ :ps:`$` module avail
+ ------------------- :sgrmp:`/usr/share/modulefiles` ------------------
+ app/1.0 app/1.2 app/1.5 app/2.0
+
+All these virtual modules are evaluated using the same :file:`.common`
+modulefile.
+Its behavior can be adapted according to the virtual module
+name being evaluated.
+
+.. code-block:: tcl
+
+ #%Module
+
+ set version [lindex [split [module-info name] /] end]
+
+ setenv APP_VERSION $version
+
+Module logger
+^^^^^^^^^^^^^
+
+Modules can log module activity through the :mconfig:`logger` and
+:mconfig:`logged_events` configuration options.
+
+The :mconfig:`logger` option defines the command used to record log messages.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module config logger "/usr/bin/logger -t modules"
+
+The :mconfig:`logged_events` option defines which module events are recorded.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Event
+ - Description
+
+ * - ``requested_cmd``
+ - Record module commands requested by users.
+
+ * - ``requested_eval``
+ - Record modulefile evaluations requested by users.
+
+ * - ``auto_eval``
+ - Record modulefile evaluations automatically triggered by Modules.
+
+Multiple events may be specified using the ``:`` separator.
+
+For example:
+
+.. parsed-literal::
+
+ :ps:`$` module config logged_events requested_cmd:requested_eval
+
+By default, no events are logged.
+
+The logger command can be customized to integrate Modules activity with an
+existing logging or monitoring infrastructure.