Transactions are the fundamental building blocks of Arweave. Every file upload, every data write, every token transfer is a transaction. There are three main ways to post them: directly with Arweave JS, through the Turbo SDK bundler, or via browser dispatch.
Choosing a Method
| Method | Best For | Max Size | Speed |
|---|---|---|---|
| Arweave JS | Full control, direct L1 transactions | No limit | Minutes (mining required) |
| Turbo SDK | Production apps, reliability, instant access | No limit | Instant (bundled) |
| Dispatch | Browser wallets, small uploads | 100 KB | Instant (bundled) |
Arweave JS
The official JavaScript SDK for interacting with the Arweave network directly.
Install
npm install arweave
Upload Data
import Arweave from 'arweave';
const arweave = Arweave.init({
host: 'arweave.net',
port: 443,
protocol: 'https'
});
// Load your wallet
const wallet = JSON.parse(fs.readFileSync('wallet.json', 'utf-8'));
// Create a data transaction
const tx = await arweave.createTransaction({
data: '<h1>Hello Permaweb</h1>'
}, wallet);
// Add tags for content type and discoverability
tx.addTag('Content-Type', 'text/html');
tx.addTag('App-Name', 'My-App');
// Sign and submit
await arweave.transactions.sign(tx, wallet);
const response = await arweave.transactions.post(tx);
console.log('Transaction ID:', tx.id);
console.log('View at:', `https://arweave.net/${tx.id}`);
Upload a File
import fs from 'fs';
const data = fs.readFileSync('photo.jpg');
const tx = await arweave.createTransaction({ data }, wallet);
tx.addTag('Content-Type', 'image/jpeg');
await arweave.transactions.sign(tx, wallet);
await arweave.transactions.post(tx);
Transaction Tags
Tags are key-value metadata attached to every transaction. They're how you organize, index, and query data on Arweave.
tx.addTag('Content-Type', 'text/html'); // MIME type for rendering
tx.addTag('App-Name', 'My-App'); // Your application identifier
tx.addTag('App-Version', '1.0.0'); // Version tracking
tx.addTag('Title', 'My Document'); // Human-readable title
tx.addTag('Unix-Time', String(Date.now() / 1000)); // Timestamp
Tags are Base64URL-encoded and limited to 2,048 bytes total per transaction.
Turbo SDK
ArDrive Turbo handles bundling, retries, and instant data availability. Recommended for production applications.
Install
npm install @ardrive/turbo-sdk
Upload with Turbo
import { TurboFactory } from '@ardrive/turbo-sdk';
import { ArweaveSigner } from '@ardrive/turbo-sdk/node';
import fs from 'fs';
// Load wallet and create signer
const jwk = JSON.parse(fs.readFileSync('wallet.json', 'utf-8'));
const signer = new ArweaveSigner(jwk);
const turbo = TurboFactory.authenticated({ signer });
// Upload a file
const filePath = './my-file.html';
const fileSize = fs.statSync(filePath).size;
const { id, owner, dataCaches, fastFinalityIndexes } = await turbo.uploadFile({
fileStreamFactory: () => fs.createReadStream(filePath),
fileSizeFactory: () => fileSize,
signal: AbortSignal.timeout(60_000),
dataItemOpts: {
tags: [
{ name: 'Content-Type', value: 'text/html' },
{ name: 'App-Name', value: 'My-App' },
],
},
});
console.log('Uploaded:', `https://arweave.net/${id}`);
Why Turbo?
- Instant availability: Transaction IDs are accessible immediately, no mining wait
- Reliability: Bundling services continuously retry posting, preventing dropped transactions
- Scale: A single bundle can hold up to 2^256 transactions
- Free tier: Uploads under 105 KiB are free via ArDrive Turbo
Dispatch
Browser wallets like Wander can dispatch small transactions (up to 100 KB) as bundled data items.
How It Works
// In a browser environment with a connected wallet
const tx = await arweave.createTransaction({
data: 'Hello from the browser!'
});
tx.addTag('Content-Type', 'text/plain');
tx.addTag('App-Name', 'My-Browser-App');
// Dispatch instead of sign + post
const result = await window.arweaveWallet.dispatch(tx);
console.log('Dispatched:', result.id);
When to Use Dispatch
- Your users are interacting through a browser wallet
- The data is small (under 100 KB)
- You want instant settlement without managing server-side wallets
Checking Transaction Status
After posting, you can check whether a transaction has been confirmed:
const status = await arweave.transactions.getStatus(txId);
console.log('Status:', status.status);
// 200 = confirmed
// 202 = pending
// 404 = not found
For Turbo uploads, the data is available immediately through gateways even before onchain confirmation.