> For the complete documentation index, see [llms.txt](https://move-book.com/llms.txt)

# Packages

Packages allow Move programmers to more easily re-use code and share it across projects. The Move
package system allows programmers to easily:

- Define a package containing Move code;
- Parameterize a package by [named addresses](./primitive-types/address);
- Import and use packages in other Move code and instantiate named addresses;
- Build packages and generate associated compilation artifacts from packages; and
- Work with a common interface around compiled Move artifacts.

## Package Layout and Manifest Syntax

A Move package source directory contains a `Move.toml` package manifest file, a generated
`Move.lock` file, and a set of subdirectories:

```plaintext
a_move_package
├── Move.toml      (required)
├── Move.lock      (generated)
├── sources        (required)
├── doc_templates  (optional)
├── examples       (optional, test & dev mode)
└── tests          (optional, test mode)
```

The directories and files labeled "required" must be present for a directory to be considered a Move
package and built. Optional directories may be present, and if so, they will be included in the
compilation process depending on the mode used to build the package. For instance, when built in
"dev" or "test" modes, the `tests` and `examples` directories will also be included.

Going through each of these in turn:

1. The [`Move.toml`](#movetoml) file is the package manifest and is required for a directory to be
   considered a Move package. This file contains metadata about the package, such as name,
   dependencies, and so on.
1. The [`Move.lock`](#movelock) file is generated by the Move CLI and contains the fixed build
   versions of the package and its dependencies. It is used to ensure consistent versions are used
   across different builds and that changes in dependencies are apparent as a change in this file.
1. The `sources` directory is required and contains the Move modules that make up the package.
   Modules in this directory will always be included in the compilation process.
1. The `doc_templates` directory can contain documentation templates that will be used when
   generating documentation for the package.
1. The `examples` directory can hold additional code to be used only for development and/or
   tutorials, this will not be included when compiled outside of `test` or `dev` modes.
1. The `tests` directory can contain Move modules that are only included when compiled in `test`
   mode or when [Move unit tests](./unit-testing) are run.

### Move.toml

The Move package manifest is defined within the `Move.toml` file and has the following syntax.
Optional fields are marked with `*`, `+` denotes one or more elements:

```toml
[package]
name = <string>
edition* = <string>      # e.g., "2024.alpha" to use the Move 2024 edition,
                         # currently in alpha. Will default to the latest stable edition if not specified.
license* = <string>              # e.g., "MIT", "GPL", "Apache 2.0"
authors* = [<string>,+]  # e.g., ["Joe Smith (joesmith@noemail.com)", "John Snow (johnsnow@noemail.com)"]

# Additional fields may be added to this section by external tools. E.g., on Sui the following sections are added:
published-at* = "<hex-address>" # The address that the package is published at. Should be set after the first publication.

[dependencies] # (Optional section) Paths to dependencies
# One or more lines declaring dependencies in the following format

# ##### Local Dependencies #####
# For local dependencies use `local = path`. Path is relative to the package root
# Local = { local = "../path/to" }
# To resolve a version conflict and force a specific version for dependency
# override you can use `override = true`
# Override = { local = "../conflicting/version", override = true }
# To instantiate address values in a dependency, use `addr_subst`
<string> = {
    local = <string>,
    override* = <bool>,
    addr_subst* = { (<string> = (<string> | "<hex_address>"))+ }
}

# ##### Git Dependencies #####
# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`.
# Revision must be supplied, it can be a branch, a tag, or a commit hash.
# If no `subdir` is specified, the root of the repository is used.
# MyRemotePackage = { git = "https://some.remote/host.git", subdir = "remote/path", rev = "main" }
<string> = {
    git = <URL ending in .git>,
    subdir=<path to dir containing Move.toml inside git repo>,
    rev=<git commit hash>,
    override* = <bool>,
    addr_subst* = { (<string> = (<string> | "<hex_address>"))+ }
}

[addresses]  # (Optional section) Declares named addresses in this package
# One or more lines declaring named addresses in the following format
# Addresses that match the name of the package must be set to `"0x0"` or they will be unable to be published.
<addr_name> = "_" | "<hex_address>" # e.g., std = "_" or my_addr = "0xC0FFEECAFE"

# Named addresses will be accessible in Move as `@name`. They're also exported:
# for example, `std = "0x1"` is exported by the Standard Library.
# alice = "0xA11CE"

[dev-dependencies] # (Optional section) Same as [dependencies] section, but only included in "dev" and "test" modes
# The dev-dependencies section allows overriding dependencies for `--test` and
# `--dev` modes. You can e.g., introduce test-only dependencies here.
# Local = { local = "../path/to/dev-build" }
<string> = {
    local = <string>,
    override* = <bool>,
    addr_subst* = { (<string> = (<string> | "<hex_address>"))+ }
}
<string> = {
    git = <URL ending in .git>,
    subdir=<path to dir containing Move.toml inside git repo>,
    rev=<git commit hash>,
    override* = <bool>,
    addr_subst* = { (<string> = (<string> | "<hex_address>"))+ }
}

[dev-addresses] # (Optional section) Same as [addresses] section, but only included in "dev" and "test" modes
# The dev-addresses section allows overwriting named addresses for the `--test`
# and `--dev` modes.
<addr_name> = "<hex_address>" # e.g., alice = "0xB0B"
```

An example of a minimal package manifest:

```toml
[package]
name = "AName"
```

An example of a more standard package manifest that also includes the Move standard library and
instantiates the named address `std` from the `LocalDep` package with the address value `0x1`:

```toml
[package]
name = "AName"
license = "Apache 2.0"

[addresses]
address_to_be_filled_in = "_"
specified_address = "0xB0B"

[dependencies]
# Local dependency
LocalDep = { local = "projects/move-awesomeness", addr_subst = { "std" = "0x1" } }
# Git dependency
MoveStdlib = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/move-stdlib", rev = "framework/mainnet" }

[dev-addresses] # For use when developing this module
address_to_be_filled_in = "0x101010101"
```

Most of the sections in the package manifest are self explanatory, but named addresses can be a bit
difficult to understand so we examine them in more detail in
[Named Addresses During Compilation](#named-addresses-during-compilation).

## Named Addresses During Compilation

Recall that Move has [named addresses](./primitive-types/address) and that named addresses cannot be
declared in Move. Instead they are declared at the package level: in the manifest file (`Move.toml`)
for a Move package you declare named addresses in the package, instantiate other named addresses,
and rename named addresses from other packages within the Move package system.

Let's go through each of these actions, and how they are performed in the package's manifest
one-by-one:

### Declaring Named Addresses

Let's say we have a Move module in `example_pkg/sources/A.move` as follows:

```move
module named_addr::a {
    public fun x(): address { @named_addr }
}
```

We could in `example_pkg/Move.toml` declare the named address `named_addr` in two different ways.
The first:

```toml
[package]
name = "example_pkg"
...
[addresses]
named_addr = "_"
```

Declares `named_addr` as a named address in the package `example_pkg` and that _this address can be
any valid address value_. In particular, an importing package can pick the value of the named
address `named_addr` to be any address it wishes. Intuitively you can think of this as
parameterizing the package `example_pkg` by the named address `named_addr`, and the package can then
be instantiated later on by an importing package.

`named_addr` can also be declared as:

```toml
[package]
name = "example_pkg"
...
[addresses]
named_addr = "0xCAFE"
```

which states that the named address `named_addr` is exactly `0xCAFE` and cannot be changed. This is
useful so other importing packages can use this named address without needing to worry about the
exact value assigned to it.

With these two different declaration methods, there are two ways that information about named
addresses can flow in the package graph:

- The former ("unassigned named addresses") allows named address values to flow from the importation
  site to the declaration site.
- The latter ("assigned named addresses") allows named address values to flow from the declaration
  site upwards in the package graph to usage sites.

With these two methods for flowing named address information throughout the package graph the rules
around scoping and renaming become important to understand.

## Scope and Renaming of Named Addresses

A named address `N` in a package `P` is in scope if:

1. `P` declares a named address `N`; or
2. A package in one of `P`'s transitive dependencies declares the named address `N` and there is a
   dependency path in the package graph between `P` and the declaring package of `N` with no
   renaming of `N`.

Additionally, every named address in a package is exported. Because of this and the above scoping
rules each package can be viewed as coming with a set of named addresses that will be brought into
scope when the package is imported, e.g., if you import `example_pkg`, that import will also bring
the `named_addr` named address into scope. Because of this, if `P` imports two packages `P1` and
`P2` both of which declare a named address `N` an issue arises in `P`: which "`N`" is meant when `N`
is referred to in `P`? The one from `P1` or `P2`? To prevent this ambiguity around which package a
named address is coming from, we enforce that the sets of scopes introduced by all dependencies in a
package are disjoint, and provide a way to _rename named addresses_ when the package that brings
them into scope is imported.

Renaming a named address when importing can be done as follows in our `P`, `P1`, and `P2` example
above:

```toml
[package]
name = "P"
...
[dependencies]
P1 = { local = "some_path_to_P1", addr_subst = { "P1N" = "N" } }
P2 = { local = "some_path_to_P2"  }
```

With this renaming `N` refers to the `N` from `P2` and `P1N` will refer to `N` coming from `P1`:

```move
module N::A {
    public fun x(): address { @P1N }
}
```

It is important to note that _renaming is not local_: once a named address `N` has been renamed to
`N2` in a package `P` all packages that import `P` will not see `N` but only `N2` unless `N` is
reintroduced from outside of `P`. This is why rule (2) in the scoping rules at the start of this
section specifies a "dependency path in the package graph between `P` and the declaring
package of `N` with no renaming of `N`."

### Instantiating Named Addresses

Named addresses can be instantiated multiple times across the package graph as long as it is always
with the same value. It is an error if the same named address (regardless of renaming) is
instantiated with differing values across the package graph.

A Move package can only be compiled if all named addresses resolve to a value. This presents issues
if the package wishes to expose an uninstantiated named address. This is what the `[dev-addresses]`
section solves in part. This section can set values for named addresses, but cannot introduce any
named addresses. Additionally, only the `[dev-addresses]` in the root package are included in `dev`
mode. For example a root package with the following manifest would not compile outside of `dev` mode
since `named_addr` would be uninstantiated:

```toml
[package]
name = "example_pkg"
...
[addresses]
named_addr = "_"

[dev-addresses]
named_addr = "0xC0FFEE"
```

## Usage and Artifacts

The Move package system comes with a command line option as part of the CLI:
`sui move <command> <command_flags>`. Unless a particular path is provided, all package commands
will run in the current enclosing Move package. The full list of commands and flags for the Move CLI
can be found by running `sui move --help`.

### Artifacts

A package can be compiled using CLI commands. This will create a `build` directory containing
build-related artifacts (including bytecode binaries, source maps, and documentation). The general
layout of the `build` directory is as follows:

```plaintext
a_move_package
├── BuildInfo.yaml
├── bytecode_modules
│   ├── dependencies
│   │   ├── <dep_pkg_name>
│   │   │   └── *.mv
│   │   ...
│   │   └──  <dep_pkg_name>
│   │       └── *.mv
│   ...
│   └── *.mv
├── docs
│   ├── dependencies
│   │   ├── <dep_pkg_name>
│   │   │   └── *.md
│   │   ...
│   │   └──  <dep_pkg_name>
│   │       └── *.md
│   ...
│   └── *.md
├── source_maps
│   ├── dependencies
│   │   ├── <dep_pkg_name>
│   │   │   └── *.mvsm
│   │   ...
│   │   └──  <dep_pkg_name>
│   │       └── *.mvsm
│   ...
│   └── *.mvsm
└── sources
    ...
    └── *.move
    ├── dependencies
    │   ├── <dep_pkg_name>
    │   │   └── *.move
    │   ...
    │   └──  <dep_pkg_name>
    │       └── *.move
    ...
    └── *.move
```

## Move.lock

The `Move.lock` file is generated at the root of the Move package when the package is built. The
`Move.lock` file contains information about your package and its build configuration, and acts as a
communication layer between the Move compiler and other tools, like chain-specific command line
interfaces and third-party package managers.

Like the `Move.toml` file, the `Move.lock` file is a text-based TOML file. Unlike the package
manifest however, the `Move.lock` file is not intended for you to edit directly. Processes on the
toolchain, like the Move compiler, access and edit the file to read and append relevant information
to it. You also must not move the file from the root, as it needs to be at the same level as the
`Move.toml` manifest in the package.

If you are using source control for your package, it's recommended practice to check in the
`Move.lock` file that corresponds with your desired built or published package. This ensures that
every build of your package is an exact replica of the original, and that changes to the build will
be apparent as changes to the `Move.lock` file.

The `Move.lock` file is a TOML file that currently contains the following fields.

**Note**: other fields may be added to the lock file either in the future, or by third-party
package managers as well.

### The `[move]` Section

This section contains the core information needed in the lockfile:

- The version of the lockfile (needed for backwards compatibility checking, and versioning lockfile
  changes in the future).
- The hash of the `Move.toml` file that was used to generate this lock file.
- The hash of the `Move.lock` file of all dependencies. If no dependencies are present, this will be
  an empty string.
- The list of dependencies.

```toml
[move]
version = <string> # Lock file version, used for backwards compatibility checking.
manifest_digest = <hash> # Sha3-256 hash of the Move.toml file that was used to generate this lock file.
deps_digest = <hash> # Sha3-256 hash of the Move.lock file of all dependencies. If no dependencies are present, this will be an empty string.
dependencies = { (name = <string>)* } # List of dependencies. Not present if there are no dependencies.
```

### The `[move.package]` Sections

After the Move compiler resolves each of the dependencies for the package it writes the location of
the dependency to the `Move.lock` file. If a dependency failed to resolve, the compiler will not
write the `Move.lock` file and the build fails. If all dependencies resolve, the `Move.lock` file
contains the locations (local and remote) of all of the package's transitive dependencies. These
will be stored in the `Move.lock` file in the following format:

```toml
# ...

[[move.package]]
name = "A"
source = { git = "https://github.com/b/c.git", subdir = "e/f", rev = "a1b2c3" }

[[move.package]]
name = "B"
source = { local = "../local-dep" }
```

### The `[move.toolchain-version]` Section

As mentioned above, additional fields may be added to the lock file by external tools. For example,
the Sui package manager adds toolchain version information to the lock file that can then be used
for on-chain source verification:

```toml
# ...

[move.toolchain-version]
compiler-version = <string> # The version of the Move compiler used to build the package, e.g. "1.21.0"
edition = <string> # The edition of the Move language used to build the package, e.g. "2024.alpha"
flavor = <string> # The flavor of the Move compiler used to build the package, e.g. "sui"
```
