What Move is, who it is for, how it works under the hood with resources and abilities, how Aptos Move and Sui Move differ, pros and cons, and how to start building today.

Move is a next generation language for secure, sandboxed, and formally verified programming where assets are first-class types. The Move Book at move-language.github.io introduces it this way, and every production deployment still reflects it: digital assets are explicit resources that cannot be copied or lost by accident.
Move takes its cue from Rust. Resources use move semantics, hence the name. When you move a coin, the original location no longer holds it. You cannot copy it implicitly, you cannot discard it by accident, and the type system tracks what you can do with it. The Move VM then enforces those guarantees again at runtime with a bytecode verifier that checks every module before it is published and again on every execution.
The first use case was the Diem blockchain at Facebook. The Move paper, Move: A Language With Programmable Resources by Sam Blackshear and colleagues, was published June 18, 2019 alongside the Libra whitepaper. Libra was renamed Diem in December 2020, the Diem Association wound down and sold assets to Silvergate in January 2022, but the language survived. Today the two major Layer 1s that run Move are Aptos, mainnet October 17, 2022, and Sui, mainnet May 3, 2023. Both were founded by former Diem engineers. The original repository at github.com/move-language/move is now archived and notes that development continues in move-language/move-on-aptos and move-language/move-sui. Aptos docs explicitly state the goal for Move to become the JavaScript of web3 for safe code involving assets.
It is less useful if your target is EVM or Solana. Move does not run there, its VM and data model are different, and its job market is smaller than Solidity and Rust. Most productive Web3 developers pair one on-chain language with one off-chain language, so Move often sits alongside TypeScript or Python for frontends and data work.
Move programs are either modules or scripts.
module 0x42::my_module { ... } and the address is the account that publishes it. Named addresses like my_addr::m are substituted to literal values at compile time but must be used by name at source level.Privileged operations enforce encapsulation. A struct can only be packed or unpacked inside the module that defines it, and its fields can only be read or mutated inside that module. Other modules see the type but must call public APIs. This is how Move enforces invariants like conservation of money at the language level.
By default a struct is linear and ephemeral: cannot be copied, cannot be dropped, and cannot be stored in global storage. That is the safe default for money. The Coin example in the Move Book shows this directly: a struct Coin has store { value: u64 } has store but not copy or drop. You must move it, store it inside a resource that has store, or explicitly unpack it. Code like let x = foo moves foo and the old binding is gone. copy foo is rejected unless the type has copy.
You relax the default by adding abilities.
Abilities are the type feature that controls what is allowed for a value. They gate bytecode instructions. The four are:
copy - value can be duplicated with copy and dereference *r. If a type has copy, all fields and type arguments inside it must have copy.drop - value can be popped or ignored at end of scope, overwritten, or discarded after a semicolon. If a type has drop, all contents must have drop.store - value can exist inside a struct held in global storage, but not necessarily as a top-level resource. This ability does not gate an operation directly, it gates existence in storage together with key.key - value can serve as a top-level key for global storage operations move_to, move_from, borrow_global, borrow_global_mut, and exists. Only the defining module can use those operators on its key type. If a type has key, all fields must have store, not necessarily key itself. That asymmetry is intentional.Builtin types map like this: bool, u8 through u256, and address have copy, drop, store. signer has only drop, it cannot be copied and cannot be put into storage directly. vector<T> and references inherit abilities from T. Generic structs like struct Cup<T> has copy, drop, store { item: T } have those abilities only when T satisfies them, so Cup<signer> does not have copy because signer does not.
A fungible coin typically has store but not copy or drop. A point in geometry has copy, drop, store. The book shows both patterns to make the contrast explicit.
Explore more guides and career playbooks