Skip to main content

Prerequisites

Before you begin, ensure you have:
  • Node.js v20 or higher installed
  • Basic familiarity with TypeScript or JavaScript
  • A code editor (VS Code recommended)
This quickstart uses the TypeScript SDK. For Rust development, see the Installation guide.

Set up your project

1

Create a new Node.js project

mkdir iota-quickstart
cd iota-quickstart
npm init -y
2

Install the IOTA SDK

Install the latest version of the IOTA TypeScript SDK:
npm install @iota/iota-sdk
For local network development, use the experimental tag: npm install @iota/iota-sdk@experimental
3

Create your first script

Create a file named quickstart.js with the following code:
const { getFullnodeUrl, IotaClient } = require('@iota/iota-sdk/client');
const { Ed25519Keypair } = require('@iota/iota-sdk/keypairs/ed25519');
const { Transaction } = require('@iota/iota-sdk/transactions');
const { getFaucetHost, requestIotaFromFaucetV0 } = require('@iota/iota-sdk/faucet');

async function main() {
    // Generate a new keypair
    const keypair = new Ed25519Keypair();
    const address = keypair.getPublicKey().toIotaAddress();
    
    console.log('Generated address:', address);

    // Connect to devnet
    const client = new IotaClient({ url: getFullnodeUrl('devnet') });
    
    // Request tokens from faucet
    console.log('Requesting tokens from faucet...');
    await requestIotaFromFaucetV0({
        host: getFaucetHost('devnet'),
        recipient: address,
    });
    
    console.log('Tokens received!');

    // Wait a moment for the transaction to be processed
    await new Promise(resolve => setTimeout(resolve, 2000));

    // Check balance
    const balance = await client.getBalance({
        owner: address,
    });
    
    console.log('Balance:', balance.totalBalance, 'NANOS');

    // Create and execute a transaction
    const tx = new Transaction();
    const [coin] = tx.splitCoins(tx.gas, [1000]);
    tx.transferObjects([coin], address);
    
    console.log('Executing transaction...');
    const result = await client.signAndExecuteTransaction({
        signer: keypair,
        transaction: tx,
    });
    
    console.log('Transaction successful!');
    console.log('Transaction digest:', result.digest);
}

main().catch(console.error);
4

Run the script

Execute your first IOTA transaction:
node quickstart.js
You should see output similar to:
Generated address: 0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231
Requesting tokens from faucet...
Tokens received!
Balance: 5000000000 NANOS
Executing transaction...
Transaction successful!
Transaction digest: 9XFneskU8tW7UxQf7tE5qFRfcN4FadtC2Z3HAZkgeETd=

Understanding the code

Let’s break down what this quickstart does:

Generate a keypair

const keypair = new Ed25519Keypair();
const address = keypair.getPublicKey().toIotaAddress();
This creates a new Ed25519 keypair (a cryptographic public/private key pair) and derives an IOTA address from it.

Connect to the network

const client = new IotaClient({ url: getFullnodeUrl('devnet') });
The IotaClient connects to the JSON-RPC server. The getFullnodeUrl() helper provides the correct endpoint for devnet.
Available networks: 'localnet', 'devnet', 'testnet', or provide a custom URL.

Request tokens from the faucet

await requestIotaFromFaucetV0({
    host: getFaucetHost('devnet'),
    recipient: address,
});
The faucet provides test tokens for development on devnet, testnet, and localnet.
The faucet has rate limits. If you exceed them, wait a few minutes before trying again.

Create and execute a transaction

const tx = new Transaction();
const [coin] = tx.splitCoins(tx.gas, [1000]);
tx.transferObjects([coin], address);

const result = await client.signAndExecuteTransaction({
    signer: keypair,
    transaction: tx,
});
This creates a transaction that:
  1. Splits 1000 NANOS from the gas coin
  2. Transfers the split coin to the same address
  3. Signs and executes the transaction on the network

Next steps

Query objects

Learn to read objects and coins owned by an address:
const objects = await client.getOwnedObjects({
    owner: address,
});

const coins = await client.getCoins({
    owner: address,
});

Call Move functions

Interact with smart contracts using moveCall:
tx.moveCall({
    target: '${packageId}::module::function',
    arguments: [tx.pure.string('arg1')],
});

Read transaction details

Query transaction information by digest:
const txn = await client.getTransaction({
    digest: 'transaction_digest_here',
    options: { showEffects: true },
});

Query events

Monitor on-chain events from transactions:
const events = await client.queryEvents({
    query: { Sender: address },
    limit: 10,
});

Common operations

const tx = new Transaction();
const [coin] = tx.splitCoins(tx.gas, [1000]);
tx.transferObjects([coin], recipientAddress);

const result = await client.signAndExecuteTransaction({
    signer: keypair,
    transaction: tx,
});

Troubleshooting

Node version errors

If you see ECONNRESET or “socket hang up” errors, verify you’re using Node.js v20 or higher:
node -v
To switch Node versions, use nvm:
nvm install 20
nvm use 20

Faucet rate limits

The faucet has rate limits per address. If you’re rate limited, either:
  • Wait a few minutes before requesting again
  • Generate a new keypair with a different address
  • Use a local network for unlimited testing

Local network setup

For development without rate limits, run a local network:
cargo run --bin iota -- start --with-faucet --force-regenesis
Then update your client to use localnet:
const client = new IotaClient({ url: getFullnodeUrl('localnet') });
See the Installation guide for setting up Rust and the IOTA CLI.

Resources

Build docs developers (and LLMs) love