Getting Started with Sui: What Actually Works
Sui is a Layer 1 blockchain built on the Move programming language, designed for parallel transaction processing through its object-centric data model. The mainnet launched in May 2023 after developmentalnet and testnet phases, developed by Mysten Labs. It uses a novel consensus mechanism called Narwhal and Tusk, which separates data dissemination from consensus ordering to achieve higher throughput than most competing chains. If you're coming from Ethereum or Solana, the first thing you need to unlearn is how transactions are structured. On Sui, everything is an object with unique IDs, ownership rules, and transfer functions. That changes how you write smart contracts and how you think about state management. Most people who try to port Solidity logic directly to Move on Sui end up with contract designs that fight the runtime instead of working with it.
Setting Up Your Environment
You need to install the Sui CLI first. The official repository is on GitHub under mystenlabs/sui. Clone it and build from source, or grab a release binary from the releases page depending on your OS. I generally recommend building from source on Linux because prebuilt binaries have occasionally had issues with certain versions of Rust toolchains, though that has improved significantly since the early 2024 patches. The command you want is usually sui client after installation. It will walk you through generating a keypair and connecting to a network. By default it points to the Sui Devnet, but you can switch between testnet, devnet, and mainnet by changing the config file located at ~/.sui/sui_config/client.yaml. Here's what matters practically: every network has different faucet URLs. The testnet faucet is at suitestfaucet.org and the devnet one is at suidevnetfaucet.com. Mainnet doesn't have a faucet, obviously, so you'll need to transfer SUI tokens from an exchange or another wallet. I hit a specific problem once where sui client kept rejecting my transaction submissions with a confusing timeout error. The RPC endpoint was fine, my gas budget was reasonable, and the transaction was valid. Turns out the issue was that I had multiple key schemes configured and the client was trying to sign with the wrong one. The fix was just running sui client active-address to verify which address was actually active, then double-checking that my keystore matched what I thought it matched. It sounds trivial but the error message pointed absolutely nowhere near that.
Writing and Deploying Your First Move Contract
Move contracts live under a package structure. Every contract needs a SuiMove.toml file at the root that declares the package name, dependencies, and local upgrades policy. The basic layout looks like this: package under the root directory, with sources/ containing your .move files, tests/ for Move-based integration tests, and specs/ for Move Prover specifications if you're doing formal verification. For a simple token contract, you'd define a struct with key and store abilities, create objects via object_init, and implement transfer functions. The critical thing beginners miss is that abilities in Move are strict. If your struct doesn't have the store ability, it can't be stored in persistent storage on-chain. If it doesn't have the key ability, it can't be used as an object identifier. This is enforced at compile time, which is both a blessing and a frustration depending on how fast you're iterating.
Get the Full Details

To deploy, you run sui client publish from your package directory. You'll need gas coins in your wallet. The deploy command returns the package ID, which you then use for any upgrade or call operations. I've seen people waste significant time on deployment failures because they had stale package references in their local cache. The workaround is running sui client gas to review what the client actually thinks you're submitting, especially the package version and upgrade policy.
Interacting With Sui Objects Programmatically
The Sui SDK supports JavaScript/TypeScript, Python, and Go. The JS SDK is the most mature. If you're building a frontend that needs to read or write Sui objects, you'll primarily use the SuiClient class with an RPC endpoint. One thing that catches people off guard: Sui objects can be shared or owned. Shared objects are accessible by any transaction, which is useful for certain contract patterns but introduces contention. If two transactions try to mutate the same shared object simultaneously, one will fail and need to be retried. In practice I've seen this become a real bottleneck on high-contention DeFi protocols during volatile market periods. The workaround is usually batching user interactions through a sequencer service that serializes writes intelligently, though that somewhat defeats the parallelism Sui promises. Reading object data uses client.getObject() with the object ID and options for full data or digest-only responses. Writing uses client.requestApplyChanges() for publishing packages or client.executeTransactionBlock() for calling functions. Gas payment is automatic when using the SDK, but you should always explicitly set a gas budget and gas object. Not doing so works until it doesn't, usually when you have multiple gas coins of different values and the client picks the wrong one.
Common Pitfalls and What They Cost You
The gas model on Sui is different from EVM chains. Gas is measured in gas units per operation, and the total cost is the sum of all operations in the transaction block. This means a single transaction that touches many objects can be expensive even if each individual operation is cheap. I've seen gas estimates wildly off because the SDK's estimation doesn't account for all the indirect object lookups that happen during complex contract interactions. When that happens, your transaction gets included but fails mid-execution rather than being rejected upfront. Another issue is the Move compiler version mismatch. Sui moves relatively fast on compiler upgrades, and packages compiled with older Move versions sometimes refuse to deploy on newer chain states. The error messages around this are vague. Check what Move compiler version your Sui client is using with sui --version and make sure it matches the network you're targeting. Running a local testnet with the same version as mainnet before deploying is the standard workaround, though that adds a step most people skip and regret later. Sui also has a maximum transaction block size limit, currently around 40,000 operations. If you're building something that processes large batches of objects in a single transaction, you'll hit this ceiling. The practical solution is splitting your work across multiple transactions with a coordinator contract that tracks progress. It's not elegant but it's how most production systems on Sui handle it.

If you need a quick reference for the current RPC endpoints, they're publicly listed in the Sui documentation. The mainnet JSON-RPC endpoint is accessible without an API key for basic queries, but if you're running anything at production scale you should use a dedicated RPC provider like Fireblocks or QuickNode to avoid rate limiting. The free endpoints typically throttle around 100 requests per second, which is fine for personal use and completely inadequate for any indexed application. The Sui Discord and the Mysten Labs GitHub discussions are the most useful places for unresolved issues. The official documentation is decent but sometimes lags behind the latest release, particularly around new object capabilities and upgrade policies. When the docs are wrong, the source code in the sui/typescript package is usually more current. For wallets, Sui Wallet is the reference implementation and supports the full feature set including object management and staking. Leap Wallet and Ethos Wallet are alternatives that add multi-chain support. I'd avoid non-custodial wallets that don't explicitly support Sui Move objects if you plan to interact with NFTs or complex smart contracts, because generic wallet interfaces often flatten object structures into forms that lose important capability metadata.