What changed in the Move 2024 edition?
November 7, 2026
Move 2024 is the current edition of Sui Move. It requires let mut for mutable variables and public on struct declarations, and it replaces friend with public(package). It also adds method syntax, enums with match, macro functions, string literals, index syntax and the single-line module a::b; label. You opt in per package by setting edition = "2024" in Move.toml, and sui move migrate handles most of the mechanical changes.
Turning it on
The edition lives in the [package] section of the manifest:
[package]
name = "my_package"
edition = "2024"2024 is the stable edition. 2024.beta and 2024.alpha give early access to features that may still change. To convert an older package, run this from the package directory:
sui move migrateIt adds mut where needed, adds public to structs and swaps friend declarations for public(package). It also renames identifiers that collide with the new keywords. The edition is per package, so you can use 2024 features even if your dependencies don't.
Breaking changes
let mut: a variable must be declaredmutto be reassigned or borrowed mutably. The same goes for function parameters and destructuring (let (mut x, y) = ...).public struct: every struct needs a visibility modifier, andpublicis the only one today. Fields stay private to the module.- Friends are deprecated:
friendandpublic(friend)give way topublic(package), which any module in the same package can call. - New keywords:
enum,for,match,mutandtypeare reserved.
New features
module book::shapes;
// Module label: no braces around the module body.
public enum Shape has copy, drop {
Circle(u64),
Rect { w: u64, h: u64 },
}
public fun area(s: &Shape): u64 {
match (s) {
Shape::Circle(r) => 3 * *r * *r,
Shape::Rect { w, h } => *w * *h,
}
}
public fun total(shapes: &vector<Shape>): u64 {
let mut sum = 0;
shapes.do_ref!(|s| sum = sum + s.area()); // macro + method syntax
sum
}- Method syntax: a function whose first parameter is a type from the same module can be called as
value.fn().use funaliases add methods to other types, andpublic use funexports them for your own types. - Enums and
match: types with several variants.matchmust be exhaustive and also works on primitives and structs. - Macros:
macro fundefinitions expand at the call site and take lambdas. Standard library macros such asdo!,map!andfold!are now the usual way to iterate (see How do loops work in Sui Move?).assert!is a regular macro, and its error code is optional. - Index syntax:
v[0],&mut v[i], and the same onTable,Bag,VecMapand others. Custom types can opt in with#[syntax(index)]. - String literals:
"hello"becomes aString, anascii::Stringor avector<u8>, depending on the expected type. See How do strings work in Sui Move?. - Positional fields:
public struct Pair(u64, u64), read by index (p.0). Abilities can come after the field list. - Abort without a code:
abortandassert!(cond)with no code derive one from the module and line. - Clever errors:
#[error] const ENotAuthorized: vector<u8> = "...";gives an abort a readable message (see How do error codes work in Sui Move?).
extend module for adding test-only members to another module is still experimental and needs 2024.alpha.
Gotchas
- Old tutorials that use
struct Foo has key {}withoutpublic,module x::y { ... }withfriend, orlet x = ...; x = ...;won't compile under 2024 until they're migrated. - The block form
module a::b { ... }still works. It's only needed to put several modules in one file. - Some framework functions were renamed alongside the move to methods. For example,
dynamic_field::exists_is deprecated in favor ofexists. Compiler warnings point to the replacements.
Sources
- Move 2024 Migration Guide, The Move Book
- Migrate to Move 2024, Sui blog
- dynamic_field.move, Sui framework source