suideveloper
New: one-tap testnet accounts with passkeys

Build on Sui, right from your browser

Guides, working snippets and a playground for Move contracts and TypeScript apps on the Sui blockchain.

Why Sui

Sui’s object model lets independent transactions run in parallel, which shapes how you design contracts and apps.

Objects, not accounts
State lives in typed objects with owners. Transactions touching different objects never contend.
Parallel by default
Owned-object transactions skip consensus; Mysticeti handles shared state with sub-second finality.
Programmable transactions
Chain up to 1,024 Move calls in one atomic transaction, composed client-side.
Passkeys and zkLogin
Users sign with Face ID or a Google login. No seed phrases, no extension.
Sponsored transactions
Pay gas on behalf of your users so onboarding feels like a normal app.
Move safety
Assets can’t be copied or dropped by accident. Whole classes of exploits disappear at compile time.

Quickstart

From zero to a published package in four steps.

  1. 1Install the Sui CLI

    Terminal
    brew install sui
  2. 2Create an address on testnet

    Terminal
    sui client new-env --alias testnet --rpc https://fullnode.testnet.sui.io:443
    sui client switch --env testnet
    sui client new-address ed25519

    Need test SUI? Import the key into the playground and fund it there.

  3. 3Write and test a Move package

    Terminal
    sui move new hello
    cd hello
    sui move test
    sources/counter.move
    module hello::counter;
    
    public struct Counter has key {
        id: UID,
        value: u64,
    }
    
    public fun create(ctx: &mut TxContext) {
        transfer::share_object(Counter {
            id: object::new(ctx),
            value: 0,
        })
    }
    
    public fun increment(c: &mut Counter) {
        c.value = c.value + 1;
    }
  4. 4Publish and call it

    Terminal
    sui client publish
    app.ts
    import { SuiGrpcClient } from '@mysten/sui/grpc'
    import { Transaction } from '@mysten/sui/transactions'
    
    const client = new SuiGrpcClient({
      network: 'testnet',
      baseUrl: 'https://fullnode.testnet.sui.io:443',
    })
    
    const tx = new Transaction()
    tx.moveCall({
      target: `${PACKAGE_ID}::counter::increment`,
      arguments: [tx.object(COUNTER_ID)],
    })
    
    await client.signAndExecuteTransaction({ signer, transaction: tx })

Common questions

Browse all questions