Skip to content

Upgrade guide from Helia 5.0.0 to Helia 6.0.0

Alex Potsides edited this page Oct 7, 2025 · 2 revisions

New features and bug fixes

Please see the release notes for the full run-down of all the new features and bug fixes in helia@6.x.x.

Migration guide

[email protected] dependency upgrade

The main feature of [email protected] is the upgrade to [email protected]. There may be nothing for you to do here, it depends on which parts of the libp2p API your application uses.

Please see the [email protected] migration guide for any changes that will be necessary.

You should upgrade all @libp2p/* modules along with libp2p to the latest releases and not upgrade them piecemeal.

Streaming blockstore

Helia's blockstore now returns streams of bytes for a CID rather than a whole block in one go. This will reduce memory usage since smaller chunks can be used and whole blocks will not need to be held in memory at any point.

Before

import { createHelia } from 'helia'
import { CID } from 'multiformats/cid'

const helia = await createHelia()
const cid = CID.parse('Qmfoo')

const block = await helia.blocks.get(cid, {
  signal: AbortSignal.timeout(5_000)
})

// use block

After

import { createHelia } from 'helia'
import { CID } from 'multiformats/cid'

const helia = await createHelia()
const cid = CID.parse('Qmfoo')

for await (const chunk of await helia.blocks.get(cid, {
  signal: AbortSignal.timeout(5_000)
})) {
  // use chunk
}

It's possible to load the whole block using it-to-buffer:

import { createHelia } from 'helia'
import { CID } from 'multiformats/cid'
import toBuffer from 'it-to-buffer'

const helia = await createHelia()
const cid = CID.parse('Qmfoo')

const block = await toBuffer(helia.blocks.get(cid, {
  signal: AbortSignal.timeout(5_000)
}))

// use block

.stream from @helia/car is now .export

The old .export method from the @helia/car module follows a different pattern to all other Helia interfaces, requiring an extra dependency on @ipld/car and accepting a CarWriter which you then need to redirect elsewhere, and also handle any errors that are thrown during the export.

The .stream method accepts one or more CID roots and returns an AsyncGenerator<Uint8Array> that can be redirected to a file, an HTTP response or somewhere else and is much simpler to use.

The .stream method has been renamed .export and the old .export method removed.

Before

import { createHelia } from 'helia'
import { car } from '@helia/car'
import { CID } from 'multiformats/cid'
import { CarWriter } from '@ipld/car'

const helia = await createHelia()
const cid = CID.parse('Qmfoo')
const c = car(helia)

const { writer, out } = await CarWriter.create([cid])

c.export(cid, writer)
  .catch(err => {
    // handle err somehow?
  })

for await (const chunk of out) {
  // ...do something with chunk
}

After

import { createHelia } from 'helia'
import { car } from '@helia/car'
import { CID } from 'multiformats/cid'

const helia = await createHelia()
const cid = CID.parse('Qmfoo')
const c = car(helia)

for await (const chunk of c.export(cid)) {
  // ...do something with chunk
}
Clone this wiki locally