Cookbook Community Meetup - 12pm ET / 5pm GMT every week on Wednesdays



Contributors: Jim Toth, Pawan Paudel, Luke Cassady-Dorion
Last Updated:


Before getting started with any of the below references, make sure you've read Bundles and Bundling from Core Concepts.


We'll be using the arbundlesopen in new window library which is a JavaScript implementation of the ANS-104 specificationopen in new window. ArBundles comes with TypeScript support.

Note: This reference assumes a NodeJS environment. Browser compatibility with ArBundles is possible but currently requires wrangling Buffer polyfills. This will be addressed in a future version of ArBundles.

npm install arbundles
yarn add arbundles

Create a Signer

In order to create Data Items, we need to first create a Signer.

import { ArweaveSigner, JWKInterface } from 'arbundles'

const jwk: JWKInterface = { /* your Arweave jwk keyfile */ }
const signer = new ArweaveSigner(jwk)

Create a DataItem

To create a DataItem, we pass some data along with a Signer to the createData() utility function.

Note: While the createData() utility function requires a Signer, the returned DataItem is not yet signed and contains a placeholder ID.

import { createData } from 'arbundles'

// Create a DataItem from a string
const myStringData: string = 'Hello, Permaweb!'
const myDataItem = createData(myStringData, signer)

// Create a DataItem from a Buffer or Uint8Array
const myBufferData: Buffer | Uint8Array = Buffer.from('Hello, Permaweb!')
const myOtherDataItem = createData(myBufferData, signer)


Create a Bundle

To create a Bundle, we pass our DataItem to the bundleAndSignData utility function and await the result.

Note: A DataItem passed to this utility function can be pre-signed as detailed in a later section.

import { bundleAndSignData } from 'arbundles'

const dataItems = [ myDataItem, myOtherDataItem ]
const bundle = await bundleAndSignData(dataItems, signer)

Create a Transaction from a Bundle

In order to post a Bundle to Arweave there ultimately needs to be a root Layer 1 Transaction containing the Bundle.

import Arweave from 'Arweave'

// Set up an Arweave client
const arweave = new Arweave({
  protocol: 'https',
  host: '',
  port: 443

// Create using ArweaveJS
const tx = await arweave.createTransaction({ data: bundle.getRaw() }, jwk)

// OR Create from the Bundle itself
const tx = await bundle.toTransaction({}, arweave, jwk)

// Sign the transaction
await arweave.transactions.sign(tx, jwk)

// Post tx to Arweave with your preferred method!

Sign a DataItem

In order to get a DataItem's ID (e.g. for use in a manifest also contained in the same bundle), we must call and await its .sign() method. If signing is successful, the DataItem will now have their unique ID and signature and are ready to be added to a Bundle.

await myDataItem.sign(signer)
await myOtherDataItem.sign(signer)

const id1 =
const id2 =

Tagging DataItem

DataItem can themselves have tags just as Layer 1 Arweave Transactions can have tags. Once an Arweave Gateway unbundles and indexes the Bundle, these DataItem tags become queryable the same way a Layer 1 Arweave Transaction's tags are queryable.

  const myStringData: string = 'Hello, Permaweb!'
  const tags = [
    { name: 'Title', value: 'Hello Permaweb' },
    { name: 'Content-Type', value: 'text/plain' }
  const myDataItem = createData(myStringData, signer, { tags })

Consuming Bundles

WARNING: Be sure that the Buffer you pass to new Bundle(buffer) does contain a Bundle, otherwise, very small Buffer being passed will crash the thread. DO NOT use new Bundle(buffer) in a production environment. Instead, see the streamable interfaceopen in new window in the ArBundles repository.

  const bundle = new Bundle(Buffer.from(
  const myDataItem = bundle.get(0)
  const myOtherDataItem = bundle.get(1)