---
title: "Dynamic Fields Migration Guide"
description: "Dynamic Fields is a new concept for Sui Move, replacing Child Objects and creating greater programming flexibility."
author: "Sam Blackshear"
datePublished: 2022-10-25
dateModified: 2026-07-16
category: "Developer Resources"
readTime: "4 min"
canonical: https://www.sui.io/blog/dynamic-fields-migration-guide
---

# Dynamic Fields Migration Guide

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](https://discord.com/channels/916379725201563759/1004638487078772736) 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_field`s 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**

-   [Dynamic Fields Documentation](https://docs.sui.io/build/programming-with-objects/ch5-dynamic-fields)
-   [Collections Documentation](https://docs.sui.io/build/programming-with-objects/ch6-collections)
-   [Dynamic Field API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/dynamic_field.move)
-   [Dynamic Object Field API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/dynamic_object_field.move)
-   [Table API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/table.move)
-   [Object Table API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/object_table.move)
-   [Bag API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/bag.move)
-   [Object Bag API](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/sources/object_bag.move)
