
Helia is the JavaScript implementation of IPFS that replaced js-ipfs. It is written in TypeScript, runs in browsers and Node.js, and lets you import only the modules you need, such as @helia/unixfs for files or @helia/verified-fetch for checked downloads.
TL;DR:
createHelia() gives you a full node with libp2p, Bitswap, and HTTP routing. createHeliaLight() starts with almost nothing, for the smallest browser bundle.@helia/http builds a node that only uses HTTP: delegated routing to find content and trustless gateways to fetch blocks.@helia/verified-fetch gives you a fetch-like call for ipfs:// URLs and checks every byte against its hash.Updated Oct 28, 2026: new answer-first opening, a diagram of where Helia sits next to AIOZ Pin, current package versions from npm, the createHelia vs createHeliaLight choice, code examples from Helia's own docs, and a migration map from js-ipfs.
Helia's project page calls it "a lean, modular, and modern TypeScript implementation of IPFS" for JavaScript and browser environments. It speaks the same protocols as any IPFS node: CIDs, Merkle DAGs, libp2p, and Bitswap. CIDs work the same way in both, so Helia can read a CID created by Kubo, and the other way round.
The big change from js-ipfs is the package layout. Helia's core only manages blocks, pins, and routing. Everything else lives in separate packages that you add when you need them: @helia/unixfs for files and folders, @helia/car for CAR archives, @helia/dag-cbor and @helia/dag-json for IPLD data, and @helia/ipns for names. A page that only reads files never ships the code for the rest.
We checked the current versions on npm on Oct 28, 2026: helia 7.1.16, @helia/unixfs 8.0.9, @helia/http 4.0.8, and @helia/verified-fetch 8.1.2.
Yes. You can check it yourself with one npm command, and this is the real output we got for the old ipfs package:
$ npm view ipfs version deprecated
version = '0.66.1'
deprecated = 'js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details'The ipfs-core package returns the same notice. A deprecated package still installs, but it gets no fixes, so you should start new work on Helia and plan a move for older apps.
Helia gives you two ways to start a node, and the choice decides your bundle size. According to the comments in Helia's source, createHelia() builds a node "using the default configuration including libp2p and HTTP routing". It also adds Bitswap and the dag-cbor, dag-json, and json codecs.
createHeliaLight() starts with no routing and no block broker, and it only supports the dag-pb and raw codecs with sha2-256 and identity hashes. The source calls it the option for "the smallest possible bundle size in web browsers", and you add only the pieces you want. Ordinary UnixFS files need nothing more than those two codecs.
This is the example from Helia's source for reading a file by CID. We did not run it:
import { createHeliaLight } from 'helia'
import { unixfs } from '@helia/unixfs'
import { CID } from 'multiformats/cid'
const helia = await createHeliaLight()
const fs = unixfs(helia)
const cid = CID.parse('QmFoo...')
for await (const buf of fs.cat(cid, {
signal: AbortSignal.timeout(5_000)
})) {
console.info(buf)
}
Browsers can't open raw TCP sockets, so a browser node can't join the network the way a server does. Helia gives you two practical routes around that.
The first is @helia/http. Its README says it configures a node whose block brokers and gateways "only run over HTTP". Content and peer routing go through the Delegated HTTP Routing API, and blocks come from Trustless Gateways. This is the README example, not run here:
import { withHTTP } from '@helia/http'
import { unixfs } from '@helia/unixfs'
import { createHeliaLight } from 'helia'
import { CID } from 'multiformats/cid'
const helia = await withHTTP(createHeliaLight(), {
delegatedRouters: [
'https://delegated-ipfs.dev'
],
recursiveGateways: [
'https://trustless-gateway.link',
'https://4everland.io'
]
}).start()
const fs = unixfs(helia)
fs.cat(CID.parse('bafyFoo'))The second is @helia/verified-fetch, which hides the node behind a familiar call: await verifiedFetch('ipfs://bafy...') returns a normal Response. Its README says all content is retrieved in a trustless way, with every byte checked by comparing hashes. Our post on how IPFS verifies content without trusting the gateway explains what that check does. For native ipfs:// links, see which browsers support them.
The concepts don't change when you move: CIDs, pins, and blocks mean the same thing, so your data and CIDs carry over. What changes is where each call lives, because the single ipfs object is split across packages.
@helia/unixfs, which has cat, ls, stat, addBytes, addFile, addDirectory, and mkdir.@helia/car. Our post on CAR files covers the format.@helia/dag-cbor or @helia/dag-json.@helia/http.Test one feature at a time, starting with reads, since unixfs(helia).cat() is the closest match to the old ipfs.cat(), then moving writes and pinning.
AIOZ Pin and Helia do different jobs, and you can use both in one app. Our official SDK, @aioznetwork/aioz-pin-sdk, is a Node.js ES module that pins files with your API key and secret key. Those keys should never reach a browser, so keep pinning on your server and send the browser only the CID.
Our docs say pinned content "becomes available on the public IPFS network". That means a Helia or verified-fetch client can fetch it by CID like any other public content, and check each block as it arrives. For plain HTTP, the public gateway URL is https://public.aiozpin.network/ipfs/{cid}. This is the documented SDK upload from our quick start, not run here because there are no AIOZ Pin credentials on this machine:
import AIOZPinClient from '@aioznetwork/aioz-pin-sdk';
let client = new AIOZPinClient("key", "secret-key")
const options = { metadata: { name: "MyCustomName" } };
client.pinFilesToIPFS({ filePaths: ['./test.png'], options })
.then((result) => { console.log(result); })
.catch((err) => { console.log(err); })Set npm pkg set type=module first, because the SDK is an ES module. The full setup, including how to create the key pair, is in the AIOZ Pin quick start.
What is Helia in IPFS? Helia is a modular TypeScript implementation of IPFS for browsers and Node.js, and the replacement for the deprecated js-ipfs.
Should I still use js-ipfs? No. Its npm packages are marked deprecated in favour of Helia and get no further fixes.
What is the difference between createHelia and createHeliaLight? createHelia includes libp2p, Bitswap, HTTP routing, and extra codecs. createHeliaLight has no routing or block broker and only the dag-pb and raw codecs, for a smaller bundle.
Can Helia run without libp2p? Yes. @helia/http builds a node that finds content through delegated HTTP routing and fetches blocks from trustless gateways.
Does Helia verify the content it downloads? Yes. Blocks are checked against their CIDs, and @helia/verified-fetch verifies every byte it returns.
Can I use Helia with AIOZ Pin? Yes. Pin from your server with the AIOZ Pin SDK, then fetch the CID in the browser with Helia or verified-fetch.

An IPFS dedicated gateway on AIOZ Pin is called a premium gateway. See what the free plan limits, what a paid plan adds, and what happens at zero balance.

Pin by CID asks a pinning service to fetch content already on IPFS and keep it. Covers the AIOZ Pin pinByHash call, statuses, and why a pin stalls on Pinning.

IPFS gateway not working? Read the status code first, then check the CID, your request rate, and whether anyone is providing the content. Here is the order.

ERC-1155 metadata on IPFS breaks when filenames ignore the {id} rule. Here is the exact 64-character format, a working folder layout, and the per-token option.

AIOZ Pin rate limits in one place: 180 requests per minute for the API, 15 per CID on the public gateway, and no predefined limit on premium gateways.

IPFS pin stuck on Pinning? Here is what Pinning, Pinned, and Failed mean on AIOZ Pin, why big directories can sit there, and how to read a pin's real state.