# ipfs-car

> Convert files to content-addressed archives (.car) and back

Latest version **3.1.0** (published 2025-10-08) · Apache-2.0 OR MIT license · 0 weekly downloads

## Install

```sh
npm install ipfs-car
pnpm add ipfs-car
yarn add ipfs-car
bun add ipfs-car
```

Provides the commands `🚘`, `ipfs-car`.

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 3.1.0 |
| Published | 2025-10-08 |
| First published | 2021-05-27 |
| Weekly downloads | 0 |
| License | Apache-2.0 OR MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18 |
| Dependencies | 11 |
| Unpacked size | 402.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 179 |
| Author | vasco-santos |
| Maintainers | alanshaw, olizilla, vascosantos, it-dag-house |
| Keywords | ipfs, content-addressable, cid, car |

## Links

- npm: https://www.npmjs.com/package/ipfs-car
- Repository: https://github.com/web3-storage/ipfs-car
- Homepage: https://github.com/web3-storage/ipfs-car#readme
- Issues: https://github.com/web3-storage/ipfs-car/issues
- npm.io page: https://npm.io/package/ipfs-car

## Dependencies (11)

- [sade](https://npm.io/package/sade.md) ^1.8.1
- [varint](https://npm.io/package/varint.md) ^6.0.0
- [@ipld/car](https://npm.io/package/@ipld/car.md) ^5.1.0
- [@ipld/dag-pb](https://npm.io/package/@ipld/dag-pb.md) ^4.0.2
- [@ipld/unixfs](https://npm.io/package/@ipld/unixfs.md) ^3.0.0
- [multiformats](https://npm.io/package/multiformats.md) ^13.0.1
- [@ipld/dag-cbor](https://npm.io/package/@ipld/dag-cbor.md) ^9.0.0
- [@ipld/dag-json](https://npm.io/package/@ipld/dag-json.md) ^10.0.1
- [files-from-path](https://npm.io/package/files-from-path.md) ^1.0.0
- [ipfs-unixfs-exporter](https://npm.io/package/ipfs-unixfs-exporter.md) ^13.0.1
- [@web3-storage/car-block-validator](https://npm.io/package/@web3-storage/car-block-validator.md) ^1.0.1

## Alternatives

- [adhdev](https://npm.io/package/adhdev.md) — 11.1K weekly downloads
- [react-slide-button](https://npm.io/package/react-slide-button.md) — 310 weekly downloads
- [better](https://npm.io/package/better.md) — 42 weekly downloads
- [react-native-swipe-image](https://npm.io/package/react-native-swipe-image.md) — 22 weekly downloads
- [nl.fokkezb.pulltorefresh](https://npm.io/package/nl.fokkezb.pulltorefresh.md) — 11 weekly downloads

## Recent versions

- 3.1.0 (latest) — 2025-10-08
- 2.0.1-pre.0 (next) — 2025-02-10
- 3.0.0 — 2025-03-26
- 2.0.0 — 2025-01-27
- 1.2.0 — 2024-01-22
- 1.1.0 — 2023-12-08
- 1.0.0 — 2023-03-20
- 0.9.2 — 2023-02-15
- 0.9.1 — 2022-10-03
- 0.8.1 — 2022-08-05
- 0.8.0 — 2022-08-02
- 0.7.0 — 2022-04-05
- 0.6.2 — 2022-02-08
- 0.6.1 — 2021-12-16
- 0.6.0 — 2021-11-22
- … 27 more at https://npm.io/package/ipfs-car/versions

## README

# ipfs-car 🚘✨⬢

> Convert files to content-addressable archives (.car) and back

[![Build](https://github.com/web3-storage/ipfs-car/actions/workflows/main.yml/badge.svg)](https://github.com/web3-storage/ipfs-car/actions/workflows/main.yml)
[![dependencies Status](https://status.david-dm.org/gh/web3-storage/ipfs-car.svg)](https://david-dm.org/web3-storage/ipfs-car)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Downloads](https://img.shields.io/npm/dm/ipfs-car.svg)](https://www.npmjs.com/package/ipfs-car)
[![Minzipped size](https://badgen.net/bundlephobia/minzip/ipfs-car)](https://bundlephobia.com/result?p=ipfs-car)

## Description

`ipfs-car` is a library and CLI tool to pack & unpack files from [Content Addressable aRchives (CAR)](https://ipld.io/specs/transport/car/) file. A thin wrapper over [@ipld/car](https://github.com/ipld/js-car) and [unix-fs](https://github.com/ipfs/js-ipfs-unixfs).

Content-addressable archives store data as blocks (a sequence of bytes) each prefixed with the [Content ID (CID)](https://docs.ipfs.tech/concepts/content-addressing/) derived from the hash of the data; typically in a file with a `.car` extension.

Use `ipfs-car` to pack your files into a .car; a portable, verifiable, IPFS compatible archive.

```sh
$ ipfs-car pack path/to/files --output my-files.car
```

or unpack files from a .car, and verify that every block matches it's CID

```sh
$ ipfs-car unpack my-files.car --output path/to/write/to
```

Fetch and locally verify files from a IPFS gateway over http

```sh
curl "https://ipfs.io/ipfs/bafybeidd2gyhagleh47qeg77xqndy2qy3yzn4vkxmk775bg2t5lpuy7pcu?format=car" | ipfs-car unpack -o images
```

## Install

```sh
# install it as a dependency
$ npm i ipfs-car

# OR use the cli without installing via `npx`
$ npx ipfs-car --help
```

## Usage

Pack files into a .car

```sh
# write a content addressed archive to stdout.
$ ipfs-car pack path/to/file/or/dir
# note: CAR data streamed to stdout will not have roots set in CAR header!

# specify the car file name.
$ ipfs-car pack path/to/files --output path/to/write/a.car

# by default, ipfs-car will wrap files in an IPFS directory.
# use --no-wrap to avoid this.
$ ipfs-car pack path/to/file --no-wrap --output path/to/write/a.car
```

Unpack files from a .car

```sh
# unpack files to a specific path.
$ ipfs-car unpack path/to/my.car --output /path/to/unpack/files/to

# unpack a specific root.
$ ipfs-car unpack path/to/my.car --root <cid1>

# unpack files from a .car on stdin.
$ cat path/to/my.car | ipfs-car unpack
```

Show the files and directories in a .car

```sh
# show the files and directories.
$ ipfs-car ls path/to/my.car

# show the files and directories, their CIDs and byte sizes.
$ ipfs-car ls path/to/my.car --verbose
```

Show the root CIDs in a .car

```sh
# show the CID roots found in the CAR header.
$ ipfs-car roots path/to/my.car

# show the CID roots found implicitly from the blocks in the file.
$ ipfs-car roots --implicit path/to/my.car
```

Show the block CIDs in a .car

```sh
# show the CIDs for all the blocks.
$ ipfs-car blocks path/to/my.car
```

Get other information about a CAR

```sh
# generate CID for a CAR.
$ ipfs-car hash path/to/my.car
```

## API

To pack files into content-addressable archives, you can use the following:

- `createFileEncoderStream` a factory function for creating a `ReadableStream` that encodes a single file into DAG `Block`s.
- `createDirectoryEncoderStream` a factory function for creating a `ReadableStream` for encoding a directory of files into DAG `Block`s.
- `CAREncoderStream` a `TransformStream` sub-class that you can write `Block`s to and read `Uint8Array` CAR file data from.

To unpack content-addressable archives to files, you should use `@ipld/car` and `ipfs-unixfs-exporter` modules.

### Examples

#### Basic single file pack

```js
import { createFileEncoderStream, CAREncoderStream } from 'ipfs-car'

const file = new Blob(['Hello ipfs-car!'])
const carStream = createFileEncoderStream(file).pipeThrough(new CAREncoderStream())

// carStream.pipeTo(somewhereWritable)
```

#### Directory pack to file system in Node.js

```js
import { Writable } from 'stream'
import { createDirectoryEncoderStream, CAREncoderStream } from 'ipfs-car'
import { filesFromPaths } from 'files-from-path'

const files = await filesFromPaths(process.argv.slice(2))

await createDirectoryEncoderStream(files)
  .pipeThrough(new CAREncoderStream())
  .pipeTo(Writable.toWeb(process.stdout))
```

Usage: `node script.js file0 file1 dir0 > my.car`.

#### Obtaining the root CID

The root CID is the final block generated by the file/directory encoder stream. Use a transform stream to record the CID of the last block generated:

```js
import { createFileEncoderStream, CAREncoderStream } from 'ipfs-car'

const file = new Blob(['Hello ipfs-car!'])
let rootCID

await createFileEncoderStream(file)
  .pipeThrough(new TransformStream({
    transform (block, controller) {
      rootCID = block.cid
      controller.enqueue(block)
    }
  }))
  .pipeThrough(new CAREncoderStream())
  .pipeTo(new WritableStream())

console.log(rootCID.toString())
```

#### Adding root CIDs to the CAR header

If you need root CIDs in the CAR header, there are two approaches you can use:

1. Buffer all the DAG blocks, then encode with known root:

```js
import { createFileEncoderStream, CAREncoderStream } from 'ipfs-car'

const file = new Blob(['Hello ipfs-car!'])
const blocks = []

// buffer the output
await createFileEncoderStream(file)
  .pipeTo(new WritableStream({ write: b => blocks.push(b) }))

const rootCID = blocks.at(-1).cid
const blockStream = new ReadableStream({
  pull (controller) {
    if (blocks.length) {
      controller.enqueue(blocks.shift())
    } else {
      controller.close()
    }
  }
})

await blockStream
  .pipeThrough(new CAREncoderStream([rootCID])) // pass root to CAR encoder
  .pipeTo(new WritableStream())
```

2. Write to disk with placeholder CID, then update after DAG is completely generated (Note: Node.js only):

```js
import fs from 'fs'
import { Writable } from 'stream'
import { CarWriter } from '@ipld/car/writer'
import { CID } from 'multiformats/cid'
import { createFileEncoderStream, CAREncoderStream } from 'ipfs-car'

// Root CID written in CAR file header before it is updated with the real root CID.
const placeholderCID = CID.parse('bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')

const file = new Blob(['Hello ipfs-car!'])
let rootCID

await createFileEncoderStream(file)
  .pipeThrough(new TransformStream({
    transform (block, controller) {
      rootCID = block.cid
      controller.enqueue(block)
    }
  }))
  .pipeThrough(new CAREncoderStream(placeholderCID))
  .pipeTo(Writable.toWeb(fs.createWriteStream('path/to/my.car')))

// update roots in CAR header
const fd = await fs.promises.open(opts.output, 'r+')
await CarWriter.updateRootsInFile(fd, [rootCID])
await fd.close()
```

#### Unpacking files from a CAR

This functionality is not provided by this library, but is easy to do with `@ipld/car` and `ipfs-unixfs-exporter` modules:

```js
import { CarIndexedReader } from '@ipld/car/indexed-reader'
import { recursive as exporter } from 'ipfs-unixfs-exporter'

const reader = await CarIndexedReader.fromFile('path/to/my.car')
const roots = await reader.getRoots()

const entries = exporter(roots[0], {
  async get (cid) {
    const block = await reader.get(cid)
    return block.bytes
  }
})

for await (const entry of entries) {
  if (entry.type === 'file' || entry.type === 'raw') {
    console.log('file', entry.path, entry.content)
  } else if (entry.type === 'directory') {
    console.log('directory', entry.path)
  }
}
```

## Contributing

Feel free to join in. All welcome. [Open an issue](https://github.com/web3-storage/ipfs-car/issues)!

## License

Dual-licensed under [MIT + Apache 2.0](https://github.com/web3-storage/ipfs-car/blob/main/LICENSE.md)

---
_Source: https://npm.io/package/ipfs-car · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
