# Creating Modules
[[toc]]
::: important
When working through the examples below, it is recommended that you start a new shell before importing an updated version of each module or command. This will help reduce any confusion caused by definitions from previous imports.
:::
## Overview
Modules (and Submodules, to be covered below) are created in one of two ways:
- Most commonly, by creating a file with a series of `export` statements of definitions to be exported from the module.
- For submodules inside a module, using the `module` command
::: tip
While it's possible to use the `module` command to create a module directly at the commandline, it's far more useful and common to store the module definitions in a file for reusability.
:::
The module file can be either:
- A file named `mod.nu`, in which case its _directory_ becomes the module name
- Any other `<module_name>.nu` file, in which case the filename becomes the module name
### Simple Module Example
Create a file named `inc.nu` with the following:
```nu
export def increment []: int -> int {
$in + 1
}
```
This is a module! We can now import it and use the `increment` command:
```nu
use inc.nu *
5 | increment
# => 6
```
Of course, you can easily distribute a file like this so that others can make use of the module as well.
## Exports
We covered the types of definitions that are available in modules briefly in the main Modules Overview above. While this might be enough explanation for an end-user, module authors will need to know _how_ to create the export definitions for:
- Commands ([`export def`](/commands/docs/export_def.md))
- Aliases ([`export alias`](/commands/docs/export_alias.md))
- Constants ([`export const`](/commands/docs/export_const.md))
- Known externals ([`export extern`](/commands/docs/export_extern.md))
- Submodules ([`export module`](/commands/docs/export_module.md))
- Imported symbols from other modules ([`export use`](/commands/docs/export_use.md))
- Environment setup ([`export-env`](/commands/docs/export-env.md))
::: tip
Only definitions marked with `export` (or `export-env` for environment variables) are accessible when the module is imported. Definitions not marked with `export` are only visible from inside the module. In some languages, these would be called "private" or "local" definitions. An example can be found below in [Additional Examples](#local-definitions).
:::
### `main` Exports
::: important
An export cannot have the same name as that of the module itself.
:::
In the [Basic Example](#basic-module-example) above, we had a module named `inc` with a command named `increment`. However, if we rename that file to `increment.nu`, it will fail to import.
```nu
mv inc.nu increment.nu
use increment.nu *
# => Error: nu::parser::named_as_module
# => ...
# => help: Module increment can't export command named
# => the same as the module. Either change the module
# => name, or export `main` command.
```
As helpfully mentioned in the error message, you can simply rename the export `main`, in which case it will take on the name of the module when imported. Edit the `increment.nu` file:
```nu
export def main []: int -> int {
$in + 1
}
```
Now it works as expected:
```nu
use ./increment.nu
2024 | increment
# => 2025
```
::: note
`main` can be used for both `export def` and `export extern` definitions.
:::
::: tip
`main` definitions are imported in the following cases:
- The entire module is imported with `use <module>` or `use <module.nu>`
- The `*` glob is used to import all of the modules definitions (e.g., `use <module> *`, etc.)
- The `main` definition is explicitly imported with `use <module> main`, `use <module> [main]`, etc.)
Conversely, the following forms do _not_ import the `main` definition:
````nu
use <module> <other_definition>
# or
use <module> [ <other_definitions> ]
:::
::: note
Additionally, `main` has special behavior if used in a script file, regardless of whether it is exported or not. See the [Scripts](scripts.html#parameterizing-scripts) chapter for more details.