With the release of Sui 0.13.0, we will be replacing the concept of Child Objects with Dynamic Fields. This is a breaking change, with the Move APIs for interacting with Child Objects in sui::transfer (transfer_to_object and transfer_to_object_id) being removed and replaced with sui::dynamic_field and sui::dynamic_object_field for working with Dynamic Fields.

To avoid errors in applications that use child objects, please follow the migration guide below and be ready to land changes when Devnet updates to 0.13.0 (watch #devnet-updates on Discord for the announcement) . To minimize downtime for your application, please wait to land changes until after the Devnet update as the new APIs for interacting with Dynamic Fields will not be available until then.

What are Dynamic Fields?

Dynamic Fields are a generalization of Child Objects. They allow Move developers on Sui to extend their structs with new data, on-the-fly.

They address the main frustration with Child Objects which require passing their ancestor ownership chain (its parent, its parent's parent, and so on up to the root object owned by the sender) via the entry function. This restriction made working with deeply nested child objects painful, and didn't support uses where the ancestor chain couldn't be known at the start of the transaction (i.e. loading child objects dynamically). With Dynamic Fields, only the root object is passed into the entry function, and its dynamic fields can be accessed on-the-fly during transaction execution. (In fact, passing a dynamic field value as an input to an entry function will now fail).

They also come with a few other improvements:

  • Holding any store value, not just objects.
  • Labeling and looking up fields by name (where a name can be any copy, drop, store value).
  • Powering new on-chain key-value stores like Table (homogeneous keys and values) and Bag (heterogeneous keys and values).

Go crazy with them! We have heard a lot of frustration around missing data structures and then being unable to implement them in Move. You should be able to efficiently implement all sorts of data structures in Move now! Whether it be a linked hash-map or a prefix trie or just a simple linked list. Dynamic fields do require reading/writing objects to storage. We still expect simple vectors to be more efficient than complex data structures for very small numbers of items.

Current Limitations

We are still actively working on some parts of Dynamic Fields, but we couldn’t wait to share this feature with you to see what you could build with it, and to get your feedback. While you are using this feature, watch out for the following known issues, which will be addressed in a future release:

  • remove for dynamic fields is currently unoptimized and will not give a full storage refund. Under the hood, the dynamic_field (and dynamic_object_field) creates Field objects to store its key-value pairs.
  • There is currently no exists_ function for dynamic_fields to check whether a field with a given name is already defined on the object.
  • There are some potential durability/consistency issues with dynamic field objects: If a validator goes down and comes back up while processing a transaction with dynamic fields, it might be unable to further process transactions with those objects. We are actively working on a solution for this.

Migration Guide

The suggestions below will work to convert any existing use of Child Objects to using Dynamic Fields, but note that in many cases, you may want to rethink your usage of the APIs. In many cases, the code can be made simpler or more end-user friendly. The examples below are designed to help with drop-in replacements to help get things running.

Replace calls to transfer_to_object with add

// Old, Child Object API
use sui::transfer;
transfer::transfer_to_object(&mut parent, child)

// New, Dynamic Field API
use sui::dynamic_object_field as ofield;
let id = object::id(&child);
ofield::add(&mut parent.id, id, child);

The new API adds a field to parent with child's ID as the name, and child as the value.

Replace ownership ancestor chains in entry funs with calls borrow, borrow_mut, or remove

(Note: this suggestion assumes that you have followed the earlier suggestion to migrate from transfer_to_object to ofield::add using the child's ID as the field name).

// Child, Parent, GrandParent are all Objects
struct Child has key, store { id: UID, /* ... */ }
struct Parent has key, store { id: UID, /* ... */ }
struct GrandParent has key, store { id: UID, /* ... */ }

// Old, Child Object API
entry fun read_child(gp: &GrandParent, p: &Parent, c: &Child) {
/* ... */
}
entry fun write_child(gp: &mut GrandParent, p: &mut Parent, c: &mut Child) {
/* ... */
}

entry fun take_child(gp: &mut GrandParent, p: &mut Parent, c: Child) {
/* ... */
}

// New, Dynamic Field API
use sui::dynamic_object_field as ofield;

entry fun read_child(gp: &GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow<ID, Parent>(&gp.id, pid);
let c = ofield::borrow<ID, Child>(&p.id, cid);
/* ... */
}

entry fun write_child(gp: &mut GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow_mut<ID, Parent>(&mut gp.id, pid);
let c = ofield::borrow_mut<ID, Child>(&mut p.id, cid);
/* ... */
}

entry fun take_child(gp: &mut GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow_mut<ID, Parent>(&mut gp.id, pid);
let c = ofield::remove<ID, Child>(&mut p.id, cid);
/* ... */
}

Learn More about Dynamic Fields

Author

Sam Blackshear

Co-Founder, CTO, Mysten Labs, Creator of Move Language

CTO of Mysten Labs and inventor of Move language. Former Principal Engineer at Meta.

Read more like this

Sui Opens SuiHub Athens as Global Adoption Surges

Greece’s unique mix of talent, geographical access, and institutional engagement makes it a strategic location for Sui’s physical global expansion. The...

2min read
Sui Foundation

From the cryptographer's desk: how we chose Sui's post-quantum signature schemes

The reasoning behind ML-DSA-65 and SLH-DSA-SHA2-128s, tested against feedback from external cryptographers, wallet providers, HSM and cloud vendors, and financial authorities, the implementation we built on, the benchmarks, and the one migration path we are deliberately not shipping yet.

10min read
Kostas Chalkias

The Agentic Economy Takes Center Stage at Sui Basecamp 2026, Singapore

Two days at Marina Bay Sands in Singapore, on October 7-8, alongside Token2049, with product reveals, leading voices in AI, and a live attempt at a sustained TPS record

5min read
Sui Foundation

BitGo Brings WBTC Natively To Sui Through LayerZero

With BitGo’s WBTC now live on Sui, Bitcoin holders can move a unified cross-chain asset seamlessly across ecosystems. Learn how to migrate and use WBTC on Sui

4min read
Sui Foundation

Sui Opens SuiHub Lagos to Catalyze Innovation in Africa's Fastest-Growing Tech Market

Lagos joins Sui’s global network of community-led hubs, expanding access to high-performance blockchain tools and empowering Africa’s next generation of builders.

2min read
Sui Foundation

From Infrastructure to Impact: Where Sui Goes Next

How foundational work across the stack is enabling the next phase of the Sui ecosystem

5min read
Abhinav Garg