Set up the Move development environment

To start building with Move in 2026, you need to install the official command-line interface (CLI) and generate a starter project. This setup gives you the compiler, test runner, and package manager required to compile and deploy smart contracts on the Sui network.

The process is straightforward and mirrors standard Node.js or Rust workflows. Once installed, you can initialize a project structure that separates your Move source code from the build artifacts.

move-based programming
1
Install the Move CLI

Run the following command in your terminal to install the Move CLI globally. This tool bundles the Move compiler and the Sui framework dependencies.

Shell
Shell
curl -L https://release.sui.io/sui-rust-v0.0.1/sui-install --location --output sui-install
chmod +x ./sui-install
./sui-install

Verify the installation by checking the version. You should see a version number that matches your installed release.

Shell
Shell
sui --version
move-based programming
2
Initialize a new project

Create a new directory for your Move module. Use the move new command to scaffold the project structure. This creates the standard Move.toml manifest and a sources directory for your code.

Shell
Shell
move new my_first_move_module
cd my_first_move_module

Your project now contains a basic hello_move module in sources/hello_move.move. You can open this file to see a simple "Hello World" example that prints to the console.

move-based programming
3
Verify the build

Compile your project to ensure the environment is configured correctly. Run the build command to check for syntax errors and type mismatches.

Shell
Shell
move build

If the build succeeds, you will see a success message in the terminal. You can then run the unit tests included in the scaffolded project to confirm everything works.

Shell
Shell
move test

Define resources with the move keyword

In Move-based programming, data isn't just a blob of bytes; it's a first-class citizen with strict ownership rules. The move keyword is the tool you use to declare these special data structures, known as resources. Unlike regular structs, which can be copied or dropped at will, a resource is unique, non-duplicable, and must be explicitly moved or destroyed. This prevents common smart contract bugs like double-spending or accidental data loss.

Think of a resource like a physical key. You can hold it, pass it to someone else, or throw it away, but you can't clone it while you still have the original. If you try to use the key twice without moving it first, the compiler stops you. This enforcement happens at compile time, giving you a safety net that traditional smart contract languages often lack.

To declare a resource, you add the move keyword before the struct definition. This tells the Move compiler that instances of this struct are unique and must follow resource semantics. Here is how that looks in practice compared to a standard data structure.

Notice the has key capability in the resource examples. This is a requirement for any resource in Move, indicating that the struct can be stored inside other resources or the global storage. Without it, the compiler will reject the definition. The move keyword is the primary signal that you are building secure, predictable state for your blockchain application.

Write a programmable transaction block

A programmable transaction block (PTB) lets you bundle multiple operations into a single atomic unit. Instead of sending separate transactions for each step—like transferring tokens, updating a ledger, and minting an NFT—you group them together. This ensures that either every step succeeds or the entire block fails, preventing partial states.

In Move, PTBs are the standard way to handle complex logic. They are efficient because they share a single execution context, reducing gas costs and network congestion. You write the logic in Move, and the block executes it as one cohesive action.

Set up the transaction builder

Start by initializing a new PTB object. This object acts as a container for your sequence of instructions. You will add operations to it one by one, defining the order of execution.

MOVE
use std::string;
use sui::coin;
use sui::tx_context::TxContext;

public fun create_ptb(ctx: &mut TxContext) {
    let ptb = ptb::new(ctx);
    // Add operations here
}

Add operations to the block

Once the PTB is initialized, you can chain operations. For example, you might first transfer some SUI tokens to a recipient, then use those tokens to mint a new resource. Each operation is added to the block in the order you write it.

MOVE
// Transfer 100 SUI to recipient
ptb::add_transfer(&mut ptb, recipient, 100);

// Mint a new item
let item = mint_item(ptb::address(&ptb));
ptb::add_publish(&mut ptb, item);

Execute the block

Finally, you commit the PTB. The blockchain executes all added operations in sequence. If any operation fails, the entire block is rolled back, ensuring consistency. This atomicity is critical for maintaining data integrity in complex decentralized applications.

MOVE
// Execute the block
ptb::execute(&mut ptb);

By using PTBs, you simplify your smart contract logic and improve performance. This approach is central to building efficient applications in Move-based programming 2026.

Verify security with static analysis

Before you deploy, use Move’s built-in static analysis tools to catch resource leaks or misuse. Think of this step as a spell-checker for your smart contract logic. It scans your code for structural issues that could lead to lost funds or broken state, long before a malicious actor sees it.

Run the Move Prover

The Move Prover is your primary defense against logical errors. It verifies that your code adheres to specific safety properties, such as ensuring that resources are never duplicated or destroyed improperly.

  1. Add assertions to your code where safety is critical. For example, assert that a token balance cannot be negative.
  2. Run move check in your terminal. This command compiles your code and runs the prover against your assertions.
  3. Review the output. If the prover succeeds, you have a mathematical guarantee that the property holds. If it fails, the tool provides a counterexample showing exactly how the violation occurs.

Check for Resource Leaks

Move’s type system is designed to make resource leaks nearly impossible, but static analysis catches subtle misuses. Ensure that every resource created in a function is either returned or consumed within the same execution path.

Use the move check command to scan for unused resources. If the analyzer flags a resource that is created but never moved or destroyed, it means that resource is effectively lost to the blockchain state. This is a common mistake for developers new to Move’s ownership model.

By integrating these tools into your daily workflow, you shift security from an afterthought to a foundational step. Catching these issues early saves time and ensures your contract is robust from day one.

Common Move Programming Mistakes

Even with Move’s strong type system, developers can still introduce bugs that lead to lost value or security vulnerabilities. The most frequent errors involve mishandling resources and ignoring access control rules. Understanding these pitfalls early prevents costly audits and runtime failures.

Dropping Resources

Move resources are first-class values that cannot be implicitly discarded. If you forget to store, transfer, or explicitly destroy a resource, the compiler will reject the code. However, accidental drops can still occur if you lose the handle to a resource before using it.

MOVE
fun example() {
    let my_coin = init_coin();
    // Error: my_coin is dropped here without being used or destroyed
}

Always ensure every resource is accounted for. Use the destroy function only when you intend to burn the resource, or store it in a struct that persists.

Violating Access Control

Move’s access control rules restrict who can read or write to private fields. A common mistake is trying to access a private field from outside its module. This breaks encapsulation and prevents the module from managing its state securely.

MOVE
module MyModule {
    struct MyStruct has key {
        value: u64
    }

    fun create() { 
        MyStruct { value: 10 } 
    }

    // Error: cannot access private field `value` here
    fun read_value(s: &MyStruct): u64 {
        s.value 
    }
}

Pre-Deployment Checklist

Before deploying your Move contract, verify the following:

  • All resources are either stored, transferred, or explicitly destroyed.
  • No private fields are accessed from outside their defining module.
  • Event emissions are used for all state changes.
  • Tests cover edge cases for resource lifecycles.
move-based programming

Watch a Move language demo

See how Move code executes in a real environment. This video by Sam Blackshear, a core contributor to the Move language, provides a practical walkthrough of Move's resource semantics and smart contract structure. It is the best visual reference for understanding how Move handles ownership and security in 2026.

Frequently asked questions about Move

Here are answers to common questions about building with Move-based programming in 2026.