Package Management Migration
Version 1.63 of the Sui CLI introduced a major overhaul of the package management system. This document describes the changes between the old and new systems and gives guidance on migrating your packages. See the package management user guide for full details on the new system.
The new system provides several benefits:
- Designed for multiple environments: You should never need multiple
Move.tomlfiles for the same package. - Predictability and offline rebuilds: Your dependencies will only change if you change your manifest.
- Flexible and local naming: You can depend on multiple packages with the same name.
- Other conveniences: Faster git downloads, stored upgrade capabilities, and tooling for local publications.
With any change of this magnitude there are bound to be some issues that crop up. Report any issues you encounter while using the new package system here.
Migrating Move.toml
Although the new package system will continue to work with existing packages, it is encouraged to migrate to the new format as soon as possible. The steps to migrate are:
- Replace the
namefield inMove.tomlwith the name that your Move code uses for your package (more info). - Replace your dependency names in
Move.tomlto match the names your Move code uses to refer to them (more info). - Remove the
[addresses]and[dev-addresses]sections ofMove.toml(more info). - If necessary, replace
[dev-dependencies]with moded dependencies.
For example, if your old Move.toml was
[package]
name = "MyPackage"
[dependencies]
Dependency = { ... }
[addresses]
my_package = "0x0"
Then your new Move.toml would be
[package]
name = "my_package"
[dependencies]
dep = { ... }
Publishing on Devnet and Localnet
Publication workflows on Mainnet and Testnet should not change with the new package system. However, publishing on ephemeral networks like localnet or devnet should use the sui client test-publish command to avoid polluting the Published.toml file with local addresses.
Instead of writing to Published.toml, the test-publish command writes the addresses to an ephemeral publication file (e.g. Pub.localnet.toml). You can select the file to use with the --pubfile-path option. If you want to publish multiple packages, you should use the same ephemeral publication file for all of the packages, so that the dependency addresses will be set correctly. You can also automate this with the --publish-unpublished-deps flag.
If you were using --with-unpublished-deps, you should almost certainly use --publish-unpublished-deps instead.
The test-publish command requires a "build environment" (Testnet or Mainnet by default, although you can define your own) to determine which dependencies to use for the ephemeral publication. Specify the build environment by passing the --build-env <env> flag.
Changes to the Move.toml file
Configure packages using a Move.toml file. The system also manages its own information in Move.lock files. The format of these files has changed.
No addresses section
In the new system, you can no longer provide named addresses. Instead, the names used for packages come from the names they are given in the [dependencies] section or in the [package] section for the package's own name.
For example, suppose you have a package called example_package that has a dependency on example_dependency, which in turn has a dependency on dep_of_dep. In your Move code, you might have:
module example_package::m;
use example_dependency::n;
use dep_of_dep::p;
In the old package management system, the Move.toml for example_package might include:
[package]
name = "Example"
[dependencies]
ExampleDep = { local = "../example_dependency" }
[addresses]
example_package = "0x0"
The names ExampleDep and Example are ignored. The source code name example_package comes from the addresses section, the name example_dependency comes from the ../example_dependency/Move.toml, and the name dep_of_dep comes from the Move.toml file of whatever package example_dependency depends on.
In the new system, the Move.toml for example_package would look like this:
[package]
name = "example_package"
[dependencies]
example_dependency = { local = "../example_dependency" }
dep_of_dep = { git = "..." }
You must define a dependency for every package that you name in your source code, although you do not need to add a dependency if you do not directly use the package. The name you use in Move.toml for the dependency is what defines the name in your Move code. The name you use in the [package] section is how you refer to your own address in Move.
package section
There are 2 changes to the [package] section of the manifest:
-
You should change the
nameused in your manifest to match the name used in your code. -
A new
implicit-dependencies = falsefield. In the old package management system, adding an explicit system dependency disabled implicit dependencies. In the new system, if you want to turn off implicit dependencies you must explicitly includeimplicit-dependencies = falsein the[package]section.
Sui advises against disabling implicit dependencies.
dependencies section
In the [dependencies] section, you must define each package that your source code refers to by name. The name you give the dependency is the same as the name used in your source code.
If you want to include a dependency on ../example and refer to it as example_dependency, you would write:
[dependencies]
example_dependency = { local = "../example" }
As in the previous system you can have git, local, or r.<resolver> dependencies, for example, r.mvr. Support for on-chain dependencies is planned, but this is not yet implemented.
In addition to the type-specific fields like rev for git dependencies, all dependencies allow an override = true. This works exactly the same way that it did in the old system.
Sui encourages consistency by requiring that the name that you give a dependency must match the name that the dependency gives itself (the name field in ../example/Move.toml). However, if you want to override the name, you can add a rename-from field to the dependency. For example, if ../example/Move.toml had name = "example", you could write:
[dependencies]
example_dependency = { local = "../example", rename-from = "example" }
Your Move code then refers to the package using example_dependency even though the Move code for the dependency refers to itself using example.
This allows you to easily mix dependencies that happen to have the same name:
[dependencies]
alices_mathlib = { git = "https://github.com/alice.git", rename-from = "mathlib" }
bobs_mathlib = { git = "https://github.com/bob.git", rename-from = "mathlib" }
Git dependencies with short SHAs
The new system handles git dependencies much more efficiently than the old system. Once your dependencies have been pinned and fetched, you no longer need to interact with git on subsequent builds. The new system only downloads the files and versions that you require, so the downloads are much faster.
However, if you have a git dependency with rev = "<commit hash>" and <commit hash> is not a full 40-character SHA, the system is forced to download the entire commit history to expand the SHA. If you want to add a dependency on a particular commit, include the entire 40-character SHA.
Changes to Move.lock
With the new package system, the Move.lock file format has changed. You should never need to read or modify Move.lock by hand, but be aware that the first time you run the new CLI on your package, it will regenerate the Move.lock file; you should check these changes into source control.
Introduction of Published.toml
The new package system no longer writes published addresses into the Move.lock file; instead they are written to a new file called Published.toml. You should check this file into source control.
For ephemeral publication, the package system will use ephemeral files (often named Pub.<env>.toml); these files should not be committed to source control. We recommend adding Pub.*.toml to your .gitignore file.