The JavaScript implementation of the IPFS protocol
+
-
+
+
-
-
-
-
-
-### Project status - `Alpha`
-
-We've come a long way, but this project is still in Alpha, lots of development is happening, API might change, beware of the Dragons 🐉..
-
-**Want to get started?** Check our [examples folder](/examples) to learn how to spawn an IPFS node in Node.js and in the Browser.
-
-**Please read this:** The [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table), a fundamental piece for automatic content and peer discovery is not yet complete. There are multiple applications that can be built without this service but nevertheless it is fundamental to getting that magic IPFS experience. The current status is that implementation is done and merged and we're working on performance issues. Expect the DHT to be available in a release very soon.
-
-[**`Weekly Core Implementations Call`**](https://github.com/ipfs/team-mgmt/issues/992)
-
-## Tech Lead
-
-[David Dias](https://github.com/daviddias)
-
-## Lead Maintainer
+## Getting started
-[Alan Shaw](https://github.com/alanshaw)
+* Read the [docs](https://github.com/ipfs/js-ipfs/tree/master/docs)
+* Ensure CORS is [correctly configured](https://github.com/ipfs/js-ipfs/blob/master/docs/CORS.md) for use with the HTTP client
+* Look into the [examples](https://github.com/ipfs-examples/js-ipfs-examples/tree/master) to learn how to spawn an IPFS node in Node.js and in the Browser
+* Consult the [Core API docs](https://github.com/ipfs/js-ipfs/tree/master/docs/core-api) to see what you can do with an IPFS node
+* Head over to https://proto.school to take the [IPFS course](https://proto.school/course/ipfs) that covers core IPFS concepts and JS APIs
+* Check out https://docs.ipfs.io for [glossary](https://docs.ipfs.io/concepts/glossary), tips, how-tos and more
+* Need help? Please ask 'How do I?' questions on https://discuss.ipfs.io
+* Find out about chat channels, the IPFS newsletter, the IPFS blog, and more in the [IPFS community space](https://docs.ipfs.io/community/).
-## Table of Contents
+## Table of Contents
-- [Install](#install)
- - [npm](#npm)
- - [Use in Node.js](#use-in-nodejs)
- - [Through command line tool](#through-command-line-tool)
- - [Use in the browser](#use-in-the-browser)
-- [Usage](#usage)
- - [IPFS CLI](#ipfs-cli)
- - [IPFS Daemon](#ipfs-daemon)
- - [IPFS Module (use IPFS as a module in Node.js or in the Browser)](#ipfs-module)
- - [Tutorials and Examples](#tutorials-and-examples)
- - [API Docs](#api)
- - [Constructor](#ipfs-constructor)
- - [Events](#events)
- - [ready](#nodeready)
- - [start](#nodestart)
- - [stop](#nodestop)
- - [Core API](#core-api)
- - [Files](#files)
- - [Graph](#graph)
- - [Name](#name)
- - [Crypto and Key Management](#crypto-and-key-management)
- - [Network](#network)
- - [Node Management](#node-management)
- - [Static types and utils](#static-types-and-utils)
-- [FAQ](#faq)
-- [Running js-ipfs with Docker](#running-js-ipfs-with-docker)
+- [Getting started](#getting-started)
+ - [Install as a CLI user](#install-as-a-cli-user)
+ - [Install as an application developer](#install-as-an-application-developer)
+- [Documentation](#documentation)
+- [Structure](#structure)
- [Packages](#packages)
-- [Development](#development)
- - [Clone and install dependencies](#clone-and-install-dependencies)
- - [Run Tests](#run-tests)
- - [Lint](#lint)
- - [Build a dist version](#build-a-dist-version)
-- [Contribute](#contribute)
- - [Want to hack on IPFS?](#want-to-hack-on-ipfs)
+- [Want to hack on IPFS?](#want-to-hack-on-ipfs)
- [License](#license)
-## Install
-
-### npm
-
-This project is available through [npm](https://www.npmjs.com/). To install, run:
-
-```bash
-> npm install ipfs
-```
-
-JS IPFS depends on native modules that are installed by [`node-gyp`](https://github.com/nodejs/node-gyp). If you have problems running the command above, it is likely that the [build tools required by `node-gyp`](https://github.com/nodejs/node-gyp#installation) are missing from your system. Please install them and then try again.
-
-We support both the Current and Active LTS versions of Node.js. Please see [nodejs.org](https://nodejs.org/) for what these currently are.
-
-This project is tested on macOS, Linux and Windows.
-
-### Use in Node.js
-
-To create an IPFS node programmatically:
-
-```js
-const IPFS = require('ipfs')
-const node = await IPFS.create()
-
-// Ready to use!
-// See https://github.com/ipfs/js-ipfs#core-api
-```
-
-### Through command line tool
-
-In order to use js-ipfs as a CLI, you must install it with the `global` flag. Run the following (even if you have ipfs installed locally):
-
-```bash
-npm install ipfs --global
-```
-
-The CLI is available by using the command `jsipfs` in your terminal. This is aliased, instead of using `ipfs`, to make sure it does not conflict with the [Go implementation](https://github.com/ipfs/go-ipfs).
-
-### Use in the browser
-
-Learn how to bundle with browserify and webpack in the [`examples`](https://github.com/ipfs/js-ipfs/tree/master/examples) folder.
-
-You can also load it using a `
-
-
-
-```
-**OR THIS:**
-
-```html
-
-
-
-
-
-```
-
-Inserting one of the above lines will make an `Ipfs` object available in the global namespace:
-
-```html
-
-```
-
-## Usage
-
-### IPFS CLI
-
-The `jsipfs` CLI, available when `js-ipfs` is installed globally, follows (should, it is a WIP) the same interface defined by `go-ipfs`, you can always use the `help` command for help menus.
-
-```sh
-# Install js-ipfs globally
-> npm install ipfs --global
-> jsipfs --help
-Commands:
- bitswap A set of commands to manipulate the bitswap agent.
- block Manipulate raw IPFS blocks.
- bootstrap Show or edit the list of bootstrap peers.
- commands List all available commands
- config [value] Get and set IPFS config values
- daemon Start a long-running daemon process
-# ...
-```
-
-`js-ipfs` uses some different default config values, so that they don't clash directly with a go-ipfs node running in the same machine. These are:
-
-- default repo location: `~/.jsipfs` (can be changed with env variable `IPFS_PATH`)
-- default swarm port: `4002`
-- default API port: `5002`
-
-### IPFS Daemon
-
-The IPFS Daemon exposes the API defined in the [HTTP API spec`](https://docs.ipfs.io/reference/api/http/). You can use any of the IPFS HTTP-API client libraries with it, such as: [js-ipfs-http-client](https://github.com/ipfs/js-ipfs-http-client).
-
-If you want a programmatic way to spawn a IPFS Daemon using JavaScript, check out [ipfsd-ctl module](https://github.com/ipfs/js-ipfsd-ctl)
-
-### IPFS Module
-
-Use the IPFS Module as a dependency of a project to __spawn in process instances of IPFS__. Create an instance by calling `await IPFS.create()`:
-
-```js
-// Create the IPFS node instance
-const node = await IPFS.create()
-// Your node is now ready to use \o/
-await node.stop()
-// node is now 'offline'
-```
-
-### [Tutorials and Examples](/examples)
-
-You can find some examples and tutorials in the [examples](/examples) folder, these exist to help you get started using `js-ipfs`.
-
-### API
-
-#### IPFS Constructor
-
-```js
-const node = await IPFS.create([options])
-```
-
-Creates and returns a ready to use instance of an IPFS node.
-
-Alternative method to construct an IPFS node
-
-The recommended method of creating a new IPFS node is to use the `IPFS.create` method. However, IPFS is a `class`, and can also be constructed using the `new` keyword:
-
-```js
-const node = new IPFS([options])
-```
-
-At this point, your node has been created but is **not** ready to use. You must either attach a listener for the "ready" event _or_ wait for the `node.ready` promise to resolve:
-
-```js
-node.on('ready', () => { /* Node is now ready to use */ })
-// OR
-await node.ready
-```
-
-
-Use the `options` argument to specify advanced configuration. It is an object with any of these properties:
-
-##### `options.repo`
-
-| Type | Default |
-|------|---------|
-| string or [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance | `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers |
-
-The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance.
-
-Example:
-
-```js
-// Store data outside your user directory
-const node = await IPFS.create({ repo: '/var/ipfs/data' })
-```
-
-##### `options.init`
-
-| Type | Default |
-|------|---------|
-| boolean or object | `true` |
-
-Initialize the repo when creating the IPFS node.
-
-If you have already initialized a repo before creating your IPFS node (e.g. you are loading a repo that was saved to disk from a previous run of your program), you must make sure to set this to `false`. Note that *initializing* a repo is different from creating an instance of [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo). The IPFS constructor sets many special properties when initializing a repo, so you should usually not try and call `repoInstance.init()` yourself.
-
-Instead of a boolean, you may provide an object with custom initialization options. All properties are optional:
-
-- `emptyRepo` (boolean) Whether to remove built-in assets, like the instructional tour and empty mutable file system, from the repo. (Default: `false`)
-- `bits` (number) Number of bits to use in the generated key pair. (Default: `2048`)
-- `privateKey` (string/PeerId) A pre-generated private key to use. Can be either a base64 string or a [PeerId](https://github.com/libp2p/js-peer-id) instance. **NOTE: This overrides `bits`.**
- ```js
- // Generating a Peer ID:
- const PeerId = require('peer-id')
- PeerId.create({ bits: 2048 }, (err, peerId) => {
- // Generates a new Peer ID, complete with public/private keypair
- // See https://github.com/libp2p/js-peer-id
- })
- ```
-- `pass` (string) A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set).
-
-##### `options.start`
-
-| Type | Default |
-|------|---------|
-| boolean | `true` |
-
- If `false`, do not automatically start the IPFS node. Instead, you’ll need to manually call [`node.start()`](#nodestart) yourself.
-
-##### `options.pass`
-
-| Type | Default |
-|------|---------|
-| string | `null` |
-
-A passphrase to encrypt/decrypt your keys.
-
-##### `options.silent`
-
-| Type | Default |
-|------|---------|
-| Boolean | `false` |
-
-Prevents all logging output from the IPFS node.
-
-##### `options.relay`
-
-| Type | Default |
-|------|---------|
-| object | `{ enabled: true, hop: { enabled: false, active: false } }` |
-
-Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs/js-ipfs/tree/master/examples/circuit-relaying) to learn more).
-
-- `enabled` (boolean): Enable circuit relay dialer and listener. (Default: `true`)
-- `hop` (object)
- - `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`)
- - `active` (boolean): Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`)
-
-##### `options.preload`
-
-| Type | Default |
-|------|---------|
-| object | `{ enabled: true, addresses: [...] }` |
-
-Configure remote preload nodes. The remote will preload content added on this node, and also attempt to preload objects requested by this node.
-
-- `enabled` (boolean): Enable content preloading (Default: `true`)
-- `addresses` (array): Multiaddr API addresses of nodes that should preload content. **NOTE:** nodes specified here should also be added to your node's bootstrap address list at [`config.Boostrap`](#optionsconfig).
-
-##### `options.EXPERIMENTAL`
-
-| Type | Default |
-|------|---------|
-| object | `{ pubsub: false, ipnsPubsub: false, sharding: false }` |
-
-Enable and configure experimental features.
-
-- `pubsub` (boolean): Enable libp2p pub-sub. (Default: `false`)
-- `ipnsPubsub` (boolean): Enable pub-sub on IPNS. (Default: `false`)
-- `sharding` (boolean): Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`)
-
-##### `options.config`
-
-| Type | Default |
-|------|---------|
-| object | [`config-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-nodejs.js) in Node.js, [`config-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-browser.js) in browsers |
-
-Modify the default IPFS node config. This object will be *merged* with the default config; it will not replace it. The default config is documented in [the js-ipfs config file doc](doc/config.md).
-
-###### Configuring Delegate Routers
-
-If you need to support Delegated Content and/or Peer Routing, you can enable it by specifying the multiaddrs of your delegate nodes in the config via `options.config.Addresses.Delegates`. If you need to run a delegate router we encourage you to run your own, with go-ipfs. You can see instructions for doing so in the [delegated routing example](https://github.com/libp2p/js-libp2p/tree/master/examples/delegated-routing).
-
-If you are not able to run your own delegate router nodes, we currently have two nodes that support delegated routing. **Important**: As many people may be leveraging these nodes, performance may be affected, which is why we recommend running your own nodes in production.
-
-Available delegate multiaddrs are:
-- `/dns4/node0.delegate.ipfs.io/tcp/443/https`
-- `/dns4/node1.delegate.ipfs.io/tcp/443/https`
-
-**Note**: If more than 1 delegate multiaddr is specified, the actual delegate will be randomly selected on startup.
-
-##### `options.ipld`
-
- | Type | Default |
-|------|---------|
-| object | [`ipld-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/ipld-nodejs.js) in Node.js, [`ipld-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/ipld-browser.js) in browsers |
-
- Modify the default IPLD config. This object will be *merged* with the default config; it will not replace it. Check IPLD [docs](https://github.com/ipld/js-ipld#ipld-constructor) for more information on the available options.
-
- > Browser config does **NOT** include by default all the IPLD formats. Only `ipld-dag-pb`, `ipld-dag-cbor` and `ipld-raw` are included.
-
- To add support for other formats we provide two options, one sync and another async.
-
- Examples for the sync option:
-
-ESM Environments
-
-```js
-import ipldGit from 'ipld-git'
-import ipldBitcoin from 'ipld-bitcoin'
-
-const node = await IPFS.create({
- ipld: {
- formats: [ipldGit, ipldBitcoin]
- }
-})
-```
-
-Commonjs Environments
-
-```js
-const node = await IPFS.create({
- ipld: {
- formats: [require('ipld-git'), require('ipld-bitcoin')]
- }
-})
-```
-
-Using script tags
-
-```html
-
-
-
-
-```
-
-
- Examples for the async option:
-
-ESM Environments
-
-```js
-const node = await IPFS.create({
- ipld: {
- async loadFormat (codec) {
- if (codec === multicodec.GIT_RAW) {
- return import('ipld-git') // This is a dynamic import
- } else {
- throw new Error('unable to load format ' + multicodec.print[codec])
- }
- }
- }
-})
-```
-> For more information about dynamic imports please check [webpack docs](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or search your bundler documention.
-
-Using dynamic imports will tell your bundler to create a separate file (normally called *chunk*) that will **only** be requested by the browser if it's really needed. This strategy will reduce your bundle size and load times without removing any functionality.
-
-With Webpack IPLD formats can even be grouped together using magic comments `import(/* webpackChunkName: "ipld-formats" */ 'ipld-git')` to produce a single file with all of them.
-
-
-Commonjs Environments
-
-```js
-const node = await IPFS.create({
- ipld: {
- async loadFormat (codec) {
- if (codec === multicodec.GIT_RAW) {
- return require('ipld-git')
- } else {
- throw new Error('unable to load format ' + multicodec.print[codec])
- }
- }
- }
-})
-```
-
-
-Using Script tags
-
-```js
-
-
-```
-
-
-
-##### `options.libp2p`
-
-| Type | Default |
-|------|---------|
-| object | [`libp2p-nodejs.js`](https://github.com/ipfs/js-ipfs/blob/master/src/core/runtime/libp2p-nodejs.js) in Node.js, [`libp2p-browser.js`](https://github.com/ipfs/js-ipfs/blob/master/src/core/runtime/libp2p-browser.js) in browsers |
-| function | [`libp2p bundle`](examples/custom-libp2p) |
-
-The libp2p option allows you to build your libp2p node by configuration, or via a bundle function. If you are looking to just modify the below options, using the object format is the quickest way to get the default features of libp2p. If you need to create a more customized libp2p node, such as with custom transports or peer/content routers that need some of the ipfs data on startup, a custom bundle is a great way to achieve this.
-
-You can see the bundle in action in the [custom libp2p example](examples/custom-libp2p).
-
-- `modules` (object):
- - `transport` (Array<[libp2p.Transport](https://github.com/libp2p/interface-transport)>): An array of Libp2p transport classes/instances to use _instead_ of the defaults. See [libp2p/interface-transport](https://github.com/libp2p/interface-transport) for details.
- - `peerDiscovery` (Array<[libp2p.PeerDiscovery](https://github.com/libp2p/interface-peer-discovery)>): An array of Libp2p peer discovery classes/instances to use _instead_ of the defaults. See [libp2p/peer-discovery](https://github.com/libp2p/interface-peer-discovery) for details. If passing a class, configuration can be passed using the config section below under the key corresponding to you module's unique `tag` (a static property on the class)
-- `config` (object):
- - `peerDiscovery` (object):
- - `autoDial` (boolean): Dial to discovered peers when under the Connection Manager min peer count watermark. (default `true`)
- - `[PeerDiscovery.tag]` (object): configuration for a peer discovery module
- - `enabled` (boolean): whether this module is enabled or disabled
- - `[custom config]` (any): other keys are specific to the module
- - `dht` (object): Configuration options for the DHT (WARNING: the current DHT implementation has performance issues, your mileage may vary)
- - `enabled` (boolean): whether the DHT is enabled or not (default `false`)
- - `kBucketSize` (number): bucket size (default `20`)
- - `randomWalk` (object): configuration for random walk
- - `enabled` (boolean): whether random DHT walking is enabled (default `false`)
-
-##### `options.connectionManager`
-
-| Type | Default |
-|------|---------|
-| object | [defaults](https://github.com/libp2p/js-libp2p-connection-manager#create-a-connectionmanager) |
-
-Configure the libp2p connection manager.
-
-#### Events
-
-IPFS instances are Node.js [EventEmitters](https://nodejs.org/dist/latest-v8.x/docs/api/events.html#events_class_eventemitter). You can listen for events by calling `node.on('event', handler)`:
-
-```js
-const node = await IPFS.create({ repo: '/var/ipfs/data' })
-node.on('error', errorObject => console.error(errorObject))
-```
-
-- `error` is always accompanied by an `Error` object with information about the error that occurred.
-
- ```js
- node.on('error', error => {
- console.error(error.message)
- })
- ```
-
-- `init` is emitted after a new repo has been initialized. It will not be emitted if you set the `init: false` option on the constructor.
-
-- `ready` is emitted when a node is ready to use. This is the final event you will receive when creating a node (after `init` and `start`).
-
- When creating a new IPFS node, you should almost always wait for the `ready` event before calling methods or interacting with the node.
-
-- `start` is emitted when a node has started listening for connections. It will not be emitted if you set the `start: false` option on the constructor.
-
-- `stop` is emitted when a node has closed all connections and released access to its repo. This is usually the result of calling [`node.stop()`](#nodestop).
-
-#### `node.ready`
-
-A promise that resolves when the node is ready to use. Should be used when constructing an IPFS node using `new`. You don't need to use this if you're using [`await IPFS.create`](#ipfs-constructor). e.g.
-
-```js
-const node = new IPFS()
-await node.ready
-// Ready to use!
-```
-
-#### `node.start()`
-
-Start listening for connections with other IPFS nodes on the network. In most cases, you do not need to call this method — `IPFS.create()` will automatically do it for you.
-
-This method is asynchronous and returns a promise.
-
-```js
-const node = await IPFS.create({ start: false })
-console.log('Node is ready to use but not started!')
-
-try {
- await node.start()
- console.log('Node started!')
-} catch (error) {
- console.error('Node failed to start!', error)
-}
-```
-
-Starting using callbacks and events
-
-If you pass a function to this method, it will be called when the node is started (Note: this method will **not** return a promise if you use a callback function).
-
-```js
-// Note: you can use the class constructor style for more
-// idiomatic callback/events style code
-const node = new IPFS({ start: false })
-
-node.on('ready', () => {
- console.log('Node is ready to use but not started!')
-
- node.start(error => {
- if (error) {
- return console.error('Node failed to start!', error)
- }
- console.log('Node started!')
- })
-})
-```
-
-Alternatively you can listen for the [`start` event](#events):
-
-```js
-// Note: you can use the class constructor style for more
-// idiomatic callback/events style code
-const node = new IPFS({ start: false })
-
-node.on('ready', () => {
- console.log('Node is ready to use but not started!')
- node.start()
-})
-
-node.on('error', error => {
- console.error('Something went terribly wrong!', error)
-})
-
-node.on('start', () => console.log('Node started!'))
-```
-
-
+## Getting Started
-#### `node.stop()`
+### Install as a CLI user
-Close and stop listening for connections with other IPFS nodes, then release access to the node’s repo.
+Installing `ipfs` globally will give you the `jsipfs` command which you can use to start a daemon running:
-This method is asynchronous and returns a promise.
-
-```js
-const node = await IPFS.create()
-console.log('Node is ready to use!')
-
-try {
- await node.stop()
- console.log('Node stopped!')
-} catch (error) {
- console.error('Node failed to stop!', error)
-}
-```
-
-Stopping using callbacks and events
-
-If you pass a function to this method, it will be called when the node is stopped (Note: this method will **not** return a promise if you use a callback function).
-
-```js
-// Note: you can use the class constructor style for more
-// idiomatic callback/events style code
-const node = new IPFS()
-
-node.on('ready', () => {
- console.log('Node is ready to use!')
-
- node.stop(error => {
- if (error) {
- return console.error('Node failed to stop cleanly!', error)
- }
- console.log('Node stopped!')
- })
-})
-```
-
-Alternatively you can listen for the [`stop` event](#events).
-
-```js
-const node = new IPFS()
-
-node.on('ready', () => {
- console.log('Node is ready to use!')
- node.stop()
-})
-
-node.on('error', error => {
- console.error('Something went terribly wrong!', error)
-})
-
-node.on('stop', () => console.log('Node stopped!'))
+```console
+$ npm install -g ipfs
+$ jsipfs daemon
+Initializing IPFS daemon...
+js-ipfs version: x.x.x
+System version: x64/darwin
+Node.js version: x.x.x
+Swarm listening on /ip4/127.0
+.... more output
```
-
-
-#### Core API
-
-[](https://github.com/ipfs/interface-ipfs-core)
-
-The IPFS core API provides all functionality that is not specific to setting up and starting or stopping a node. This API is available directly on an IPFS instance, on the command line (when using the CLI interface), and as an HTTP REST API. For a complete reference, see [](https://github.com/ipfs/interface-ipfs-core).
-
-All the API methods aside from streaming methods (ones that end in `ReadableStream` or `PullStream`) are asynchronous and return Promises, but _also_ accept callbacks.
-
-The core API is grouped into several areas:
-
-#### Files
-- [Regular Files API](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md)
- - [`ipfs.add(data, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add)
- - [`ipfs.addPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addpullstream)
- - [`ipfs.addReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addreadablestream)
- - [`ipfs.addFromStream(stream)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromstream)
- - [`ipfs.addFromFs(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromfs)
- - [`ipfs.addFromUrl(url, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromurl)
- - [`ipfs.cat(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#cat)
- - [`ipfs.catPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catpullstream)
- - [`ipfs.catReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catreadablestream)
- - [`ipfs.get(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#get)
- - [`ipfs.getPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getpullstream)
- - [`ipfs.getReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getreadablestream)
- - [`ipfs.ls(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#ls)
- - [`ipfs.lsPullStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lspullstream)
- - [`ipfs.lsReadableStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lsreadablestream)
-- [MFS (mutable file system) specific](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#mutable-file-system)
- - [`ipfs.files.cp([from, to])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp)
- - [`ipfs.files.flush([path])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush)
- - [`ipfs.files.ls([path], [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesls)
- - [`ipfs.files.mkdir(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmkdir)
- - [`ipfs.files.mv([from, to])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmv)
- - [`ipfs.files.read(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread)
- - [`ipfs.files.readPullStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadpullstream)
- - [`ipfs.files.readReadableStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadreadablestream)
- - [`ipfs.files.rm(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesrm)
- - [`ipfs.files.stat(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesstat)
- - [`ipfs.files.write(path, content, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#fileswrite)
+You can then add a file:
-
-#### Graph
-
-- [dag](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md)
- - [`ipfs.dag.put(dagNode, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagput)
- - [`ipfs.dag.get(cid, [path], [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagget)
- - [`ipfs.dag.tree(cid, [path], [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagtree)
-
-- [pin](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md)
- - [`ipfs.pin.add(hash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinadd)
- - [`ipfs.pin.ls([hash], [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinls)
- - [`ipfs.pin.rm(hash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinrm)
-
-- [object (legacy)](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md)
- - [`ipfs.object.new([template])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectnew)
- - [`ipfs.object.put(obj, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectput)
- - [`ipfs.object.get(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectget)
- - [`ipfs.object.data(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectdata)
- - [`ipfs.object.links(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectlinks)
- - [`ipfs.object.stat(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectstat)
- - [`ipfs.object.patch.addLink(multihash, DAGLink, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchaddlink)
- - [`ipfs.object.patch.rmLink(multihash, DAGLink, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchrmlink)
- - [`ipfs.object.patch.appendData(multihash, data, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchappenddata)
- - [`ipfs.object.patch.setData(multihash, data, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchsetdata)
-
-#### Block
-
-- [block](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md)
- - [`ipfs.block.get(cid, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockget)
- - [`ipfs.block.put(block, cid)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockput)
- - [`ipfs.block.stat(cid)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockstat)
-- [bitswap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BITSWAP.md)
- - [`ipfs.bitswap.wantlist([peerId])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapwantlist)
- - [`ipfs.bitswap.stat()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapstat)
-
-#### Name
-
-- [name](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md)
- - [`ipfs.name.publish(value, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepublish)
- - [`ipfs.name.pubsub.cancel(arg)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubcancel)
- - [`ipfs.name.pubsub.state()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubstate)
- - [`ipfs.name.pubsub.subs()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubsubs)
- - [`ipfs.name.resolve(value, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#nameresolve)
-
-#### Crypto and Key Management
-
-- [key](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/KEY.md)
- - [`ipfs.key.export(name, password)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyexport)
- - [`ipfs.key.gen(name, options)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keygen)
- - [`ipfs.key.import(name, pem, password)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyimport)
- - [`ipfs.key.list()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keylist)
- - [`ipfs.key.rename(oldName, newName)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrename)
- - [`ipfs.key.rm(name)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrm)
-
-- crypto (not implemented yet)
-
-#### Network
-
-- [bootstrap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BOOTSTRAP.md)
- - [`ipfs.bootstrap.list()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraplist)
- - [`ipfs.bootstrap.add(addr, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstrapadd)
- - [`ipfs.bootstrap.rm(peer, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraprm)
-
-- [dht](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DHT.md)
- - [`ipfs.dht.findPeer(peerId)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindpeer)
- - [`ipfs.dht.findProvs(multihash)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindprovs)
- - [`ipfs.dht.get(key)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtget)
- - [`ipfs.dht.provide(cid)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtprovide)
- - [`ipfs.dht.put(key, value)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtput)
- - [`ipfs.dht.query(peerId)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtquery)
-
-- [pubsub](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md)
- - [`ipfs.pubsub.subscribe(topic, handler, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubsubscribe)
- - [`ipfs.pubsub.unsubscribe(topic, handler)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubunsubscribe)
- - [`ipfs.pubsub.publish(topic, data)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubpublish)
- - [`ipfs.pubsub.ls(topic)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubls)
- - [`ipfs.pubsub.peers(topic)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubpeers)
-
-- [libp2p](https://github.com/libp2p/interface-libp2p). Every IPFS instance also exposes the libp2p SPEC at `ipfs.libp2p`. The formal interface for this SPEC hasn't been defined but you can find documentation at its implementations:
- - [Node.js bundle](./src/core/runtime/libp2p-nodejs.js)
- - [Browser Bundle](./src/core/runtime/libp2p-browser.js)
- - [libp2p baseclass](https://github.com/libp2p/js-libp2p)
-
-- [swarm](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md)
- - [`ipfs.swarm.addrs()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#swarmaddrs)
- - [`ipfs.swarm.connect(addr)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#swarmconnect)
- - [`ipfs.swarm.disconnect(addr)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#swarmdisconnect)
- - [`ipfs.swarm.peers([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#swarmpeers)
-
-#### Node Management
-
-- [miscellaneous operations](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md)
- - [`ipfs.id()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#id)
- - [`ipfs.version()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#version)
- - [`ipfs.ping(peerId, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#ping)
- - [`ipfs.pingReadableStream(peerId, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#pingreadablestream)
- - [`ipfs.pingPullStream(peerId, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#pingpullstream)
- - `ipfs.init([options])`
- - `ipfs.start()`
- - [`ipfs.stop()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#stop)
- - `ipfs.isOnline()`
- - [`ipfs.resolve(name, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#resolve)
- - [`ipfs.dns(name, [options]`](https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#dns)
-
-- [repo](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md)
- - `ipfs.repo.init`
- - [`ipfs.repo.stat([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md#repostat)
- - [`ipfs.repo.version()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md#repoversion)
- - `ipfs.repo.gc([options])` (not implemented yet)
-
-- [stats](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md)
- - [`ipfs.stats.bitswap()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#statsbitswap)
- - [`ipfs.stats.bw([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#statsbw)
- - [`ipfs.stats.bwPullStream([options]) -> Pull Stream`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#statsbwpullstream)
- - [`ipfs.stats.bwReadableStream([options]) -> Readable Stream`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#statsbwreadablestream)
- - [`ipfs.stats.repo([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#statsrepo)
-
-- [config](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md)
- - [`ipfs.config.get([key])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configget)
- - [`ipfs.config.set(key, value)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configset)
- - [`ipfs.config.replace(config)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configreplace)
-
-#### Static types and utils
-
-Aside from the default export, `ipfs` exports various types and utilities that are included in the bundle:
-
-- [`crypto`](https://www.npmjs.com/package/libp2p-crypto)
-- [`isIPFS`](https://www.npmjs.com/package/is-ipfs)
-- [`Buffer`](https://www.npmjs.com/package/buffer)
-- [`PeerId`](https://www.npmjs.com/package/peer-id)
-- [`PeerInfo`](https://www.npmjs.com/package/peer-info)
-- [`multiaddr`](https://www.npmjs.com/package/multiaddr)
-- [`multibase`](https://www.npmjs.com/package/multibase)
-- [`multihash`](https://www.npmjs.com/package/multihashes)
-- [`multihashing`](https://www.npmjs.com/package/multihashing-async)
-- [`multicodec`](https://www.npmjs.com/package/multicodec)
-- [`CID`](https://www.npmjs.com/package/cids)
-
-These can be accessed like this, for example:
-
-```js
-const { CID } = require('ipfs')
-// ...or from an es-module:
-import { CID } from 'ipfs'
+```console
+$ jsipfs add ./hello-world.txt
+added QmXXY5ZxbtuYj6DnfApLiGstzPN7fvSyigrRee3hDWPCaf hello-world.txt
```
-## FAQ
-
-#### How to enable WebRTC support for js-ipfs in the Browser
+### Install as an application developer
-To add a WebRTC transport to your js-ipfs node, you must add a WebRTC multiaddr. To do that, simple override the config.Addresses.Swarm array which contains all the multiaddrs which the IPFS node will use. See below:
+If you do not need to run a command line daemon, use the `ipfs-core` package - it has all the features of `ipfs` but in a lighter package:
-```JavaScript
-const node = await IPFS.create({
- config: {
- Addresses: {
- Swarm: [
- '/dns4/wrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star'
- ]
- }
- }
-})
-
-// your instance with WebRTC is ready
+```console
+$ npm install ipfs-core
```
-**Important:** This transport usage is kind of unstable and several users have experienced crashes. Track development of a solution at https://github.com/ipfs/js-ipfs/issues/1088.
-
-#### Is there WebRTC support for js-ipfs with Node.js?
+Then start a node in your app:
-Yes, however, bear in mind that there isn't a 100% stable solution to use WebRTC in Node.js, use it at your own risk. The most tested options are:
+```javascript
+import * as IPFS from 'ipfs-core'
-- [wrtc](https://npmjs.org/wrtc) - Follow the install instructions.
-- [electron-webrtc](https://npmjs.org/electron-webrtc)
-
-To add WebRTC support in a IPFS node instance, do:
-
-```JavaScript
-const wrtc = require('wrtc') // or require('electron-webrtc')()
-const WStar = require('libp2p-webrtc-star')
-const wstar = new WStar({ wrtc })
-
-const node = await IPFS.create({
- repo: 'your-repo-path',
- // start: false,
- config: {
- Addresses: {
- Swarm: [
- "/ip4/0.0.0.0/tcp/4002",
- "/ip4/127.0.0.1/tcp/4003/ws",
- "/dns4/wrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star"
- ]
- }
- },
- libp2p: {
- modules: {
- transport: [wstar],
- peerDiscovery: [wstar.discovery]
- }
- }
-})
-
-// your instance with WebRTC is ready
-```
-
-To add WebRTC support to the IPFS daemon, you only need to install one of the WebRTC modules globally:
-
-```bash
-npm install wrtc --global
-# or
-npm install electron-webrtc --global
+const ipfs = await IPFS.create()
+const { cid } = await ipfs.add('Hello world')
+console.info(cid)
+// QmXXY5ZxbtuYj6DnfApLiGstzPN7fvSyigrRee3hDWPCaf
```
-Then, update your IPFS Daemon config to include the multiaddr for this new transport on the `Addresses.Swarm` array. Add: `"/dns4/wrtc-star.discovery.libp2p.io/wss/p2p-webrtc-star"`
-
-#### How can I configure an IPFS node to use a custom `signaling endpoint` for my WebRTC transport?
+## Documentation
-You'll need to execute a compatible `signaling server` ([libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star) works) and include the correct configuration param for your IPFS node:
+* [Concepts](https://docs.ipfs.io/concepts/)
+* [Config](./docs/CONFIG.md)
+* [Core API](./docs/core-api)
+* [Examples](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples)
+* [Development](./docs/DEVELOPMENT.md)
-- provide the [`multiaddr`](https://github.com/multiformats/multiaddr) for the `signaling server`
-
-```JavaScript
-const node = await IPFS.create({
- repo: 'your-repo-path',
- config: {
- Addresses: {
- Swarm: [
- '/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star'
- ]
- }
- }
-})
-```
+## Structure
-The code above assumes you are running a local `signaling server` on port `9090`. Provide the correct values accordingly.
-
-#### Is there a more stable alternative to webrtc-star that offers a similar functionality?
-
-Yes, websocket-star! A WebSockets based transport that uses a Relay to route the messages. To enable it, just do:
-
-```JavaScript
-const node = await IPFS.create({
- config: {
- Addresses: {
- Swarm: [
- '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star'
- ]
- }
- }
-})
-
-// your instance with websocket-star is ready
-```
-
-#### I see some slowness when hopping between tabs Chrome with IPFS nodes, is there a reason why?
-
-Yes, unfortunately, due to [Chrome aggressive resource throttling policy](https://github.com/ipfs/js-ipfs/issues/611), it cuts freezes the execution of any background tab, turning an IPFS node that was running on that webpage into a vegetable state.
-
-A way to mitigate this in Chrome, is to run your IPFS node inside a Service Worker, so that the IPFS instance runs in a background process. You can learn how to install an IPFS node as a service worker in here the repo [ipfs-service-worker](https://github.com/ipfs/ipfs-service-worker)
-
-#### Can I use IPFS in my Electron App?
-
-Yes you can and in many ways. Read https://github.com/ipfs/notes/issues/256 for the multiple options.
-
-We now support Electron v5.0.0 without the need to rebuilt native modules.
-Still if you run into problems with native modules follow these instructions [here](https://electronjs.org/docs/tutorial/using-native-node-modules).
-
-#### Have more questions?
-
-Ask for help in our forum at https://discuss.ipfs.io or in IRC (#ipfs on Freenode).
-
-## Running js-ipfs with Docker
-
-We have automatic Docker builds setup with Docker Hub: https://hub.docker.com/r/ipfs/js-ipfs/
-
-All branches in the Github repository maps to a tag in Docker Hub, except `master` Git branch which is mapped to `latest` Docker tag.
-
-You can run js-ipfs like this:
-
-```
-$ docker run -it -p 4002:4002 -p 4003:4003 -p 5002:5002 -p 9090:9090 ipfs/js-ipfs:latest
-
-initializing ipfs node at /root/.jsipfs
-generating 2048-bit RSA keypair...done
-peer identity: Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
-to get started, enter:
-
- jsipfs files cat /ipfs/QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr/readme
-
-Initializing daemon...
-Using wrtc for webrtc support
-Swarm listening on /ip4/127.0.0.1/tcp/4003/ws/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
-Swarm listening on /ip4/172.17.0.2/tcp/4003/ws/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
-Swarm listening on /ip4/127.0.0.1/tcp/4002/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
-Swarm listening on /ip4/172.17.0.2/tcp/4002/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
-API is listening on: /ip4/0.0.0.0/tcp/5002
-Gateway (readonly) is listening on: /ip4/0.0.0.0/tcp/9090
-Daemon is ready
-
-$ curl --silent localhost:5002/api/v0/id | jq .ID
-"Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS"
-```
+This project is broken into several modules, their purposes are:
+* [`/packages/interface-ipfs-core`](./packages/interface-ipfs-core) Tests to ensure adherence of an implementation to the spec
+* [`/packages/ipfs`](./packages/ipfs) An aggregator module that bundles the core implementation, the CLI, HTTP API server and daemon
+* [`/packages/ipfs-cli`](./packages/ipfs-cli) A CLI to the core implementation
+* [`/packages/ipfs-core`](./packages/ipfs-core) The core implementation
+* [`/packages/ipfs-core-types`](./packages/ipfs-core-types) Typescript definitions for the core API
+* [`/packages/ipfs-core-utils`](./packages/ipfs-core-utils) Helpers and utilities common to core and the HTTP RPC API client
+* [`/packages/ipfs-daemon`](./packages/ipfs-daemon) Run js-IPFS as a background daemon
+* [`/packages/ipfs-grpc-client`](./packages/ipfs-grpc-client) A gRPC client for js-IPFS
+* [`/packages/ipfs-grpc-protocol`](./packages/ipfs-grpc-protocol) Shared module between the gRPC client and server
+* [`/packages/ipfs-grpc-server`](./packages/ipfs-grpc-server) A gRPC-over-websockets server for js-IPFS
+* [`/packages/ipfs-http-client`](./packages/ipfs-http-client) A client for the RPC-over-HTTP API presented by both js-ipfs and go-ipfs
+* [`/packages/ipfs-http-server`](./packages/ipfs-http-server) JS implementation of the [Kubo RPC HTTP API](https://docs.ipfs.io/reference/kubo/rpc/)
+* [`/packages/ipfs-http-gateway`](./packages/ipfs-http-gateway) JS implementation of the [IPFS HTTP Gateway](https://docs.ipfs.io/concepts/ipfs-gateway/)
+* [`/packages/ipfs-http-response`](./packages/ipfs-http-response) Creates a HTTP response for a given IPFS Path
+* [`/packages/ipfs-message-port-client`](./packages/ipfs-message-port-client) A client for the RPC-over-message-port API presented by js-ipfs running in a shared worker
+* [`/packages/ipfs-message-port-protocol`](./packages/ipfs-message-port-protocol) Code shared by the message port client & server
+* [`/packages/ipfs-message-port-server`](./packages/ipfs-message-port-server) The server that receives requests from ipfs-message-port-client
## Packages
-Listing of the main packages used in the IPFS ecosystem. There are also three specifications worth linking here:
-
-- [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core)
-- [`HTTP API spec`](https://docs.ipfs.io/reference/api/http)
-- [`cli spec`](https://github.com/ipfs/specs/tree/master/public-api/cli)
-
-> This table is generated using the module `package-table` with `package-table --data=package-list.json`.
+List of the main packages that make up the IPFS ecosystem.
| Package | Version | Deps | CI/Travis | Coverage | Lead Maintainer |
| ---------|---------|---------|---------|---------|--------- |
| **Files** |
-| [`ipfs-unixfs-engine`](//github.com/ipfs/js-ipfs-unixfs-engine) | [](//github.com/ipfs/js-ipfs-unixfs-engine/releases) | [](https://david-dm.org/ipfs/js-ipfs-unixfs-engine) | [](https://travis-ci.com/ipfs/js-ipfs-unixfs-engine) | [](https://codecov.io/gh/ipfs/js-ipfs-unixfs-engine) | [Alex Potsides](mailto:alex.potsides@protocol.ai) |
-| **DAG** |
-| [`ipld`](//github.com/ipld/js-ipld) | [](//github.com/ipld/js-ipld/releases) | [](https://david-dm.org/ipld/js-ipld) | [](https://travis-ci.com/ipld/js-ipld) | [](https://codecov.io/gh/ipld/js-ipld) | [Volker Mische](mailto:volker.mische@gmail.com) |
-| [`ipld-dag-pb`](//github.com/ipld/js-ipld-dag-pb) | [](//github.com/ipld/js-ipld-dag-pb/releases) | [](https://david-dm.org/ipld/js-ipld-dag-pb) | [](https://travis-ci.com/ipld/js-ipld-dag-pb) | [](https://codecov.io/gh/ipld/js-ipld-dag-pb) | [Volker Mische](mailto:volker.mische@gmail.com) |
-| [`ipld-dag-cbor`](//github.com/ipld/js-ipld-dag-cbor) | [](//github.com/ipld/js-ipld-dag-cbor/releases) | [](https://david-dm.org/ipld/js-ipld-dag-cbor) | [](https://travis-ci.com/ipld/js-ipld-dag-cbor) | [](https://codecov.io/gh/ipld/js-ipld-dag-cbor) | [Volker Mische](mailto:volker.mische@gmail.com) |
+| [`ipfs-unixfs`](//github.com/ipfs/js-ipfs-unixfs) | [](//github.com/ipfs/js-ipfs-unixfs/releases) | [](https://david-dm.org/ipfs/js-ipfs-unixfs) | [](https://travis-ci.com/ipfs/js-ipfs-unixfs) | [](https://codecov.io/gh/ipfs/js-ipfs-unixfs) | [Alex Potsides](mailto:alex.potsides@protocol.ai) |
| **Repo** |
-| [`ipfs-repo`](//github.com/ipfs/js-ipfs-repo) | [](//github.com/ipfs/js-ipfs-repo/releases) | [](https://david-dm.org/ipfs/js-ipfs-repo) | [](https://travis-ci.com/ipfs/js-ipfs-repo) | [](https://codecov.io/gh/ipfs/js-ipfs-repo) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`ipfs-repo`](//github.com/ipfs/js-ipfs-repo) | [](//github.com/ipfs/js-ipfs-repo/releases) | [](https://david-dm.org/ipfs/js-ipfs-repo) | [](https://travis-ci.com/ipfs/js-ipfs-repo) | [](https://codecov.io/gh/ipfs/js-ipfs-repo) | [Alex Potsides](mailto:alex@achingbrain.net) |
+| [`ipfs-repo-migrations`](//github.com/ipfs/js-ipfs-repo-migrations) | [](//github.com/ipfs/js-ipfs-repo-migrations/releases) | [](https://david-dm.org/ipfs/js-ipfs-repo-migrations) | [](https://travis-ci.com/ipfs/js-ipfs-repo-migrations) | [](https://codecov.io/gh/ipfs/js-ipfs-repo-migrations) | N/A |
| **Exchange** |
-| [`ipfs-block-service`](//github.com/ipfs/js-ipfs-block-service) | [](//github.com/ipfs/js-ipfs-block-service/releases) | [](https://david-dm.org/ipfs/js-ipfs-block-service) | [](https://travis-ci.com/ipfs/js-ipfs-block-service) | [](https://codecov.io/gh/ipfs/js-ipfs-block-service) | [Volker Mische](mailto:volker.mische@gmail.com) |
-| [`ipfs-bitswap`](//github.com/ipfs/js-ipfs-bitswap) | [](//github.com/ipfs/js-ipfs-bitswap/releases) | [](https://david-dm.org/ipfs/js-ipfs-bitswap) | [](https://travis-ci.com/ipfs/js-ipfs-bitswap) | [](https://codecov.io/gh/ipfs/js-ipfs-bitswap) | [Dirk McCormick](mailto:dirk@protocol.ai) |
-| **libp2p** |
-| [`libp2p`](//github.com/libp2p/js-libp2p) | [](//github.com/libp2p/js-libp2p/releases) | [](https://david-dm.org/libp2p/js-libp2p) | [](https://travis-ci.com/libp2p/js-libp2p) | [](https://codecov.io/gh/libp2p/js-libp2p) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`libp2p-circuit`](//github.com/libp2p/js-libp2p-circuit) | [](//github.com/libp2p/js-libp2p-circuit/releases) | [](https://david-dm.org/libp2p/js-libp2p-circuit) | [](https://travis-ci.com/libp2p/js-libp2p-circuit) | [](https://codecov.io/gh/libp2p/js-libp2p-circuit) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`libp2p-floodsub`](//github.com/libp2p/js-libp2p-floodsub) | [](//github.com/libp2p/js-libp2p-floodsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-floodsub) | [](https://travis-ci.com/libp2p/js-libp2p-floodsub) | [](https://codecov.io/gh/libp2p/js-libp2p-floodsub) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
-| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
-| [`libp2p-mdns`](//github.com/libp2p/js-libp2p-mdns) | [](//github.com/libp2p/js-libp2p-mdns/releases) | [](https://david-dm.org/libp2p/js-libp2p-mdns) | [](https://travis-ci.com/libp2p/js-libp2p-mdns) | [](https://codecov.io/gh/libp2p/js-libp2p-mdns) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`libp2p-bootstrap`](//github.com/libp2p/js-libp2p-bootstrap) | [](//github.com/libp2p/js-libp2p-bootstrap/releases) | [](https://david-dm.org/libp2p/js-libp2p-bootstrap) | [](https://travis-ci.com/libp2p/js-libp2p-bootstrap) | [](https://codecov.io/gh/libp2p/js-libp2p-bootstrap) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
-| [`libp2p-secio`](//github.com/libp2p/js-libp2p-secio) | [](//github.com/libp2p/js-libp2p-secio/releases) | [](https://david-dm.org/libp2p/js-libp2p-secio) | [](https://travis-ci.com/libp2p/js-libp2p-secio) | [](https://codecov.io/gh/libp2p/js-libp2p-secio) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
-| [`libp2p-tcp`](//github.com/libp2p/js-libp2p-tcp) | [](//github.com/libp2p/js-libp2p-tcp/releases) | [](https://david-dm.org/libp2p/js-libp2p-tcp) | [](https://travis-ci.com/libp2p/js-libp2p-tcp) | [](https://codecov.io/gh/libp2p/js-libp2p-tcp) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
-| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [](//github.com/libp2p/js-libp2p-websocket-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [](https://travis-ci.com/libp2p/js-libp2p-websocket-star) | [](https://codecov.io/gh/libp2p/js-libp2p-websocket-star) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [](//github.com/libp2p/js-libp2p-websockets/releases) | [](https://david-dm.org/libp2p/js-libp2p-websockets) | [](https://travis-ci.com/libp2p/js-libp2p-websockets) | [](https://codecov.io/gh/libp2p/js-libp2p-websockets) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`pull-mplex`](//github.com/libp2p/pull-mplex) | [](//github.com/libp2p/pull-mplex/releases) | [](https://david-dm.org/libp2p/pull-mplex) | [](https://travis-ci.com/libp2p/pull-mplex) | [](https://codecov.io/gh/libp2p/pull-mplex) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| **Data Types** |
-| [`ipfs-block`](//github.com/ipfs/js-ipfs-block) | [](//github.com/ipfs/js-ipfs-block/releases) | [](https://david-dm.org/ipfs/js-ipfs-block) | [](https://travis-ci.com/ipfs/js-ipfs-block) | [](https://codecov.io/gh/ipfs/js-ipfs-block) | [Volker Mische](mailto:volker.mische@gmail.com) |
-| [`ipfs-unixfs`](//github.com/ipfs/js-ipfs-unixfs) | [](//github.com/ipfs/js-ipfs-unixfs/releases) | [](https://david-dm.org/ipfs/js-ipfs-unixfs) | [](https://travis-ci.com/ipfs/js-ipfs-unixfs) | [](https://codecov.io/gh/ipfs/js-ipfs-unixfs) | [Alex Potsides](mailto:alex.potsides@protocol.ai) |
-| [`peer-id`](//github.com/libp2p/js-peer-id) | [](//github.com/libp2p/js-peer-id/releases) | [](https://david-dm.org/libp2p/js-peer-id) | [](https://travis-ci.com/libp2p/js-peer-id) | [](https://codecov.io/gh/libp2p/js-peer-id) | [Pedro Teixeira](mailto:i@pgte.me) |
-| [`peer-info`](//github.com/libp2p/js-peer-info) | [](//github.com/libp2p/js-peer-info/releases) | [](https://david-dm.org/libp2p/js-peer-info) | [](https://travis-ci.com/libp2p/js-peer-info) | [](https://codecov.io/gh/libp2p/js-peer-info) | [Pedro Teixeira](mailto:i@pgte.me) |
-| [`multiaddr`](//github.com/multiformats/js-multiaddr) | [](//github.com/multiformats/js-multiaddr/releases) | [](https://david-dm.org/multiformats/js-multiaddr) | [](https://travis-ci.com/multiformats/js-multiaddr) | [](https://codecov.io/gh/multiformats/js-multiaddr) | [Jacob Heun](mailto:jacobheun@gmail.com) |
-| [`multihashes`](//github.com/multiformats/js-multihash) | [](//github.com/multiformats/js-multihash/releases) | [](https://david-dm.org/multiformats/js-multihash) | [](https://travis-ci.com/multiformats/js-multihash) | [](https://codecov.io/gh/multiformats/js-multihash) | [David Dias](mailto:daviddias@ipfs.io) |
-| **Crypto** |
-| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [](//github.com/libp2p/js-libp2p-crypto/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto) | [](https://travis-ci.com/libp2p/js-libp2p-crypto) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto) | [Friedel Ziegelmayer](mailto:dignifiedquire@gmail.com) |
-| [`libp2p-keychain`](//github.com/libp2p/js-libp2p-keychain) | [](//github.com/libp2p/js-libp2p-keychain/releases) | [](https://david-dm.org/libp2p/js-libp2p-keychain) | [](https://travis-ci.com/libp2p/js-libp2p-keychain) | [](https://codecov.io/gh/libp2p/js-libp2p-keychain) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`ipfs-bitswap`](//github.com/ipfs/js-ipfs-bitswap) | [](//github.com/ipfs/js-ipfs-bitswap/releases) | [](https://david-dm.org/ipfs/js-ipfs-bitswap) | [](https://travis-ci.com/ipfs/js-ipfs-bitswap) | [](https://codecov.io/gh/ipfs/js-ipfs-bitswap) | [Dirk McCormick](mailto:dirk@protocol.ai) |
+| **IPNS** |
+| [`ipns`](//github.com/ipfs/js-ipns) | [](//github.com/ipfs/js-ipns/releases) | [](https://david-dm.org/ipfs/js-ipns) | [](https://travis-ci.com/ipfs/js-ipns) | [](https://codecov.io/gh/ipfs/js-ipns) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
| **Generics/Utils** |
-| [`ipfs-http-client`](//github.com/ipfs/js-ipfs-http-client) | [](//github.com/ipfs/js-ipfs-http-client/releases) | [](https://david-dm.org/ipfs/js-ipfs-http-client) | [](https://travis-ci.com/ipfs/js-ipfs-http-client) | [](https://codecov.io/gh/ipfs/js-ipfs-http-client) | [Alan Shaw](mailto:alan@tableflip.io) |
-| [`ipfs-multipart`](//github.com/ipfs/js-ipfs-multipart) | [](//github.com/ipfs/js-ipfs-multipart/releases) | [](https://david-dm.org/ipfs/js-ipfs-multipart) | [](https://travis-ci.com/ipfs/js-ipfs-multipart) | [](https://codecov.io/gh/ipfs/js-ipfs-multipart) | N/A |
-| [`is-ipfs`](//github.com/ipfs/is-ipfs) | [](//github.com/ipfs/is-ipfs/releases) | [](https://david-dm.org/ipfs/is-ipfs) | [](https://travis-ci.com/ipfs/is-ipfs) | [](https://codecov.io/gh/ipfs/is-ipfs) | [Marcin Rataj](mailto:lidel@lidel.org) |
-| [`multihashing`](//github.com/multiformats/js-multihashing) | [](//github.com/multiformats/js-multihashing/releases) | [](https://david-dm.org/multiformats/js-multihashing) | [](https://travis-ci.com/multiformats/js-multihashing) | [](https://codecov.io/gh/multiformats/js-multihashing) | [Hugo Dias](mailto:mail@hugodias.me) |
-| [`mafmt`](//github.com/multiformats/js-mafmt) | [](//github.com/multiformats/js-mafmt/releases) | [](https://david-dm.org/multiformats/js-mafmt) | [](https://travis-ci.com/multiformats/js-mafmt) | [](https://codecov.io/gh/multiformats/js-mafmt) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
-
-## Development
-
-### Clone and install dependencies
-
-```sh
-> git clone https://github.com/ipfs/js-ipfs.git
-> cd js-ipfs
-> npm install
-```
-
-### Run tests
-
-```sh
-# run all the unit tests
-> npm test
-
-# run individual tests (findprovs)
-> npm run test -- --grep findprovs
-
-# run just IPFS tests in Node.js
-> npm run test:node
-
-# run just IPFS core tests
-> npm run test:node:core
-
-# run just IPFS HTTP-API tests
-> npm run test:node:http
-
-# run just IPFS CLI tests
-> npm run test:node:cli
-
-# run just IPFS core tests in the Browser (Chrome)
-> npm run test:browser
-
-# run some interface tests (block API) on Node.js
-> npm run test:node:interface -- --grep '.block'
-```
-
-### Run interop tests
-
-Run the interop tests with https://github.com/ipfs/interop
-
-### Run benchmark tests
-
-```sh
-# run all the benchmark tests
-> npm run benchmark
-
-# run just IPFS benchmarks in Node.js
-> npm run benchmark:node
-
-# run just IPFS benchmarks in Node.js for an IPFS instance
-> npm run benchmark:node:core
-
-# run just IPFS benchmarks in Node.js for an IPFS daemon
-> npm run benchmark:node:http
-
-# run just IPFS benchmarks in the browser (Chrome)
-> npm run benchmark:browser
-```
-
-### Lint
-
-**Conforming to linting rules is a prerequisite to commit to js-ipfs.**
-
-```sh
-> npm run lint
-```
-
-### Build a dist version
-
-```sh
-> npm run build
-```
-
-### [Runtime Support](https://github.com/ipfs/js-ipfs/issues/536)
-
-### Code Architecture and folder Structure
-
-
-
-##### Source code
-
-```Bash
-> tree src -L 2
-src # Main source code folder
-├── cli # Implementation of the IPFS CLI
-│ └── ...
-├── http # The HTTP-API implementation of IPFS as defined by HTTP API spec
-├── core # IPFS implementation, the core (what gets loaded in browser)
-│ ├── components # Each of IPFS subcomponent
-│ └── ...
-└── ...
-```
-
-### Monitoring
-
-The HTTP API exposed with js-ipfs can also be used for exposing metrics about
-the running js-ipfs node and other Node.js metrics.
-
-To enable it, you need to set the environment variable `IPFS_MONITORING` (any value)
-
-Once the environment variable is set and the js-ipfs daemon is running, you can get
-the metrics (in prometheus format) by making a GET request to the following endpoint:
-
-```
-http://localhost:5002/debug/metrics/prometheus
-```
-
-### IPFS Architecture
-
-
-
-[Annotated version](https://user-images.githubusercontent.com/1211152/47606420-b6265780-da13-11e8-923b-b365a8534e0e.png)j
-
-What does this image explain?
+| [`ipfs-utils`](//github.com/ipfs/js-ipfs) | [](//github.com/ipfs/js-ipfs/releases) | [](https://david-dm.org/ipfs/js-ipfs) | [](https://travis-ci.com/ipfs/js-ipfs) | [](https://codecov.io/gh/ipfs/js-ipfs) | [Hugo Dias](mailto:hugomrdias@gmail.com) |
+| [`ipfs-http-client`](//github.com/ipfs/js-ipfs) | [](//github.com/ipfs/js-ipfs/releases) | [](https://david-dm.org/ipfs/js-ipfs) | [](https://travis-ci.com/ipfs/js-ipfs) | [](https://codecov.io/gh/ipfs/js-ipfs) | [Alex Potsides](mailto:alex@achingbrain.net) |
+| [`ipfs-http-response`](//github.com/ipfs/js-ipfs-http-response) | [](//github.com/ipfs/js-ipfs-http-response/releases) | [](https://david-dm.org/ipfs/js-ipfs-http-response) | [](https://travis-ci.com/ipfs/js-ipfs-http-response) | [](https://codecov.io/gh/ipfs/js-ipfs-http-response) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`ipfsd-ctl`](//github.com/ipfs/js-ipfsd-ctl) | [](//github.com/ipfs/js-ipfsd-ctl/releases) | [](https://david-dm.org/ipfs/js-ipfsd-ctl) | [](https://travis-ci.com/ipfs/js-ipfsd-ctl) | [](https://codecov.io/gh/ipfs/js-ipfsd-ctl) | [Hugo Dias](mailto:mail@hugodias.me) |
+| [`is-ipfs`](//github.com/ipfs/is-ipfs) | [](//github.com/ipfs/is-ipfs/releases) | [](https://david-dm.org/ipfs/is-ipfs) | [](https://travis-ci.com/ipfs/is-ipfs) | [](https://codecov.io/gh/ipfs/is-ipfs) | [Marcin Rataj](mailto:lidel@lidel.org) |
+| [`aegir`](//github.com/ipfs/aegir) | [](//github.com/ipfs/aegir/releases) | [](https://david-dm.org/ipfs/aegir) | [](https://travis-ci.com/ipfs/aegir) | [](https://codecov.io/gh/ipfs/aegir) | [Hugo Dias](mailto:hugomrdias@gmail.com) |
+| **libp2p** |
+| [`libp2p`](//github.com/libp2p/js-libp2p) | [](//github.com/libp2p/js-libp2p/releases) | [](https://david-dm.org/libp2p/js-libp2p) | [](https://travis-ci.com/libp2p/js-libp2p) | [](https://codecov.io/gh/libp2p/js-libp2p) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`peer-id`](//github.com/libp2p/js-peer-id) | [](//github.com/libp2p/js-peer-id/releases) | [](https://david-dm.org/libp2p/js-peer-id) | [](https://travis-ci.com/libp2p/js-peer-id) | [](https://codecov.io/gh/libp2p/js-peer-id) | [Vasco Santos](mailto:santos.vasco10@gmail.com) |
+| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [](//github.com/libp2p/js-libp2p-crypto/releases) | [](https://david-dm.org/libp2p/js-libp2p-crypto) | [](https://travis-ci.com/libp2p/js-libp2p-crypto) | [](https://codecov.io/gh/libp2p/js-libp2p-crypto) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`libp2p-floodsub`](//github.com/libp2p/js-libp2p-floodsub) | [](//github.com/libp2p/js-libp2p-floodsub/releases) | [](https://david-dm.org/libp2p/js-libp2p-floodsub) | [](https://travis-ci.com/libp2p/js-libp2p-floodsub) | [](https://codecov.io/gh/libp2p/js-libp2p-floodsub) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`libp2p-gossipsub`](//github.com/ChainSafe/gossipsub-js) | [](//github.com/ChainSafe/gossipsub-js/releases) | [](https://david-dm.org/ChainSafe/gossipsub-js) | [](https://travis-ci.com/ChainSafe/gossipsub-js) | [](https://codecov.io/gh/ChainSafe/gossipsub-js) | [Cayman Nava](mailto:caymannava@gmail.com) |
+| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [](//github.com/libp2p/js-libp2p-kad-dht/releases) | [](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [](https://travis-ci.com/libp2p/js-libp2p-kad-dht) | [](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`libp2p-mdns`](//github.com/libp2p/js-libp2p-mdns) | [](//github.com/libp2p/js-libp2p-mdns/releases) | [](https://david-dm.org/libp2p/js-libp2p-mdns) | [](https://travis-ci.com/libp2p/js-libp2p-mdns) | [](https://codecov.io/gh/libp2p/js-libp2p-mdns) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`libp2p-bootstrap`](//github.com/libp2p/js-libp2p-bootstrap) | [](//github.com/libp2p/js-libp2p-bootstrap/releases) | [](https://david-dm.org/libp2p/js-libp2p-bootstrap) | [](https://travis-ci.com/libp2p/js-libp2p-bootstrap) | [](https://codecov.io/gh/libp2p/js-libp2p-bootstrap) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`@chainsafe/libp2p-noise`](//github.com/ChainSafe/js-libp2p-noise) | [](//github.com/ChainSafe/js-libp2p-noise/releases) | [](https://david-dm.org/ChainSafe/js-libp2p-noise) | [](https://travis-ci.com/ChainSafe/js-libp2p-noise) | [](https://codecov.io/gh/ChainSafe/js-libp2p-noise) | N/A |
+| [`libp2p-tcp`](//github.com/libp2p/js-libp2p-tcp) | [](//github.com/libp2p/js-libp2p-tcp/releases) | [](https://david-dm.org/libp2p/js-libp2p-tcp) | [](https://travis-ci.com/libp2p/js-libp2p-tcp) | [](https://codecov.io/gh/libp2p/js-libp2p-tcp) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [](https://travis-ci.com/libp2p/js-libp2p-webrtc-star) | [](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [](//github.com/libp2p/js-libp2p-websockets/releases) | [](https://david-dm.org/libp2p/js-libp2p-websockets) | [](https://travis-ci.com/libp2p/js-libp2p-websockets) | [](https://codecov.io/gh/libp2p/js-libp2p-websockets) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`libp2p-mplex`](//github.com/libp2p/js-libp2p-mplex) | [](//github.com/libp2p/js-libp2p-mplex/releases) | [](https://david-dm.org/libp2p/js-libp2p-mplex) | [](https://travis-ci.com/libp2p/js-libp2p-mplex) | [](https://codecov.io/gh/libp2p/js-libp2p-mplex) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`libp2p-delegated-content-routing`](//github.com/libp2p/js-libp2p-delegated-content-routing) | [](//github.com/libp2p/js-libp2p-delegated-content-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-content-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-content-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-content-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| [`libp2p-delegated-peer-routing`](//github.com/libp2p/js-libp2p-delegated-peer-routing) | [](//github.com/libp2p/js-libp2p-delegated-peer-routing/releases) | [](https://david-dm.org/libp2p/js-libp2p-delegated-peer-routing) | [](https://travis-ci.com/libp2p/js-libp2p-delegated-peer-routing) | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+| **IPLD** |
+| [`@ipld/dag-pb`](//github.com/ipld/js-dag-pb) | [](//github.com/ipld/js-dag-pb/releases) | [](https://david-dm.org/ipld/js-dag-pb) | [](https://travis-ci.com/ipld/js-dag-pb) | [](https://codecov.io/gh/ipld/js-dag-pb) | N/A |
+| [`@ipld/dag-cbor`](//github.com/ipld/js-dag-cbor) | [](//github.com/ipld/js-dag-cbor/releases) | [](https://david-dm.org/ipld/js-dag-cbor) | [](https://travis-ci.com/ipld/js-dag-cbor) | [](https://codecov.io/gh/ipld/js-dag-cbor) | N/A |
+| **Multiformats** |
+| [`multiformats`](//github.com/multiformats/js-multiformats) | [](//github.com/multiformats/js-multiformats/releases) | [](https://david-dm.org/multiformats/js-multiformats) | [](https://travis-ci.com/multiformats/js-multiformats) | [](https://codecov.io/gh/multiformats/js-multiformats) | N/A |
+| [`mafmt`](//github.com/multiformats/js-mafmt) | [](//github.com/multiformats/js-mafmt/releases) | [](https://david-dm.org/multiformats/js-mafmt) | [](https://travis-ci.com/multiformats/js-mafmt) | [](https://codecov.io/gh/multiformats/js-mafmt) | [Vasco Santos](mailto:vasco.santos@moxy.studio) |
+| [`multiaddr`](//github.com/multiformats/js-multiaddr) | [](//github.com/multiformats/js-multiaddr/releases) | [](https://david-dm.org/multiformats/js-multiaddr) | [](https://travis-ci.com/multiformats/js-multiaddr) | [](https://codecov.io/gh/multiformats/js-multiaddr) | [Jacob Heun](mailto:jacobheun@gmail.com) |
+
+> This table is generated using the module [`package-table`](https://www.npmjs.com/package/package-table) with `package-table --data=package-list.json`.
+
+## Want to hack on IPFS?
-- IPFS uses `ipfs-repo` which picks `fs` or `indexeddb` as its storage drivers, depending if it is running in Node.js or in the Browser.
-- The exchange protocol, `bitswap`, uses the Block Service which in turn uses the Repo, offering a get and put of blocks to the IPFS implementation.
-- The DAG API (previously Object) comes from the IPLD Resolver, it can support several IPLD Formats (i.e: dag-pb, dag-cbor, etc).
-- The Files API uses `ipfs-unixfs-engine` to import and export files to and from IPFS.
-- libp2p, the network stack of IPFS, uses libp2p to dial and listen for connections, to use the DHT, for discovery mechanisms, and more.
+[](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
-## Contribute
+The IPFS implementation in JavaScript needs your help! There are a few things you can do right now to help out:
-IPFS implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out:
+Read the [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md) and [JavaScript Contributing Guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md).
-- Go through the modules below and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
-- **Perform code reviews**. More eyes will help (a) speed the project along, (b) ensure quality, and (c) reduce possible future bugs.
-- Take a look at go-ipfs and some of the planning repositories or issues: for instance, the [libp2p spec](https://github.com/ipfs/specs/pull/19). Contributions here that would be most helpful are **top-level comments** about how it should look based on our understanding. Again, the more eyes the better.
+- **Check out existing issues** The [issue list](https://github.com/ipfs/js-ipfs/issues) has many that are marked as ['help wanted'](https://github.com/ipfs/js-ipfs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22) or ['difficulty:easy'](https://github.com/ipfs/js-ipfs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Adifficulty%3Aeasy) which make great starting points for development, many of which can be tackled with no prior IPFS knowledge
+- **Look at the [IPFS Roadmap](https://github.com/ipfs/roadmap)** This are the high priority items being worked on right now
+- **Perform code reviews** More eyes will help
+ a. speed the project along
+ b. ensure quality, and
+ c. reduce possible future bugs.
- **Add tests**. There can never be enough tests.
-### Want to hack on IPFS?
-
-[](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
-
## License
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fipfs%2Fjs-ipfs?ref=badge_large)
diff --git a/RELEASE.md b/RELEASE.md
deleted file mode 100644
index c8e9c9ca0d..0000000000
--- a/RELEASE.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Release Template
-
-> short tl;dr; of the release
-
-# 🗺 What's left for release
-
-# 🔦 Highlights
-
-# 🏗 API Changes
-
-# ✅ Release Checklist
-
-- Robustness and quality
- - [ ] Ensure that all tests are passing, this includes:
- - [ ] unit
- - [ ] interop
- - [ ] sharness
- - [ ] Publish a release candidate to npm
- ```sh
- # Minor prerelease (e.g. 0.33.1 -> 0.34.0-rc.0)
- $ npx aegir release --type preminor --preid rc --dist-tag next
-
- # Increment prerelease (e.g. 0.34.0-rc.0 -> 0.34.0-rc.1)
- $ npx aegir release --type prerelease --preid rc --dist-tag next
- ```
- - [ ] Run tests of the following projects with the new release:
- - [ ] [ipfs-pubsub-room](https://github.com/ipfs-shipyard/ipfs-pubsub-room)
- - [ ] [peer-base](https://github.com/peer-base/peer-base)
- - [ ] [ipfs-log](https://github.com/orbitdb/ipfs-log)
- - [ ] [orbit-db](https://github.com/orbitdb/orbit-db)
- - [ ] [service-worker-gateway](https://github.com/ipfs-shipyard/service-worker-gateway)
- - [ ] Update js.ipfs.io examples and Service Worker Gateway to use latest js-ipfs
-- Documentation
- - [ ] Ensure that README.md is up to date
- - [ ] Ensure that all the examples run
-- Communication
- - [ ] Create the release issue
- - [ ] Take a snapshot between of everyone that has contributed to this release (including its subdeps in IPFS, libp2p, IPLD and multiformats) using [`name-your-contributors`](https://www.npmjs.com/package/name-your-contributors). Generate a nice markdown list with [this script](https://gist.github.com/alanshaw/5a2d9465c5a05b201d949551bdb1fcc3).
- - [ ] Announcements (both pre-release and post-release)
- - [ ] Twitter
- - [ ] IRC
- - [ ] Reddit
- - [ ] [discuss.ipfs.io](https://discuss.ipfs.io/c/announcements)
- - [ ] Announce it on the [IPFS Users mlist](https://groups.google.com/forum/#!forum/ipfs-users)
- - [ ] Blog post
- - [ ] Copy release notes to the [GitHub Release description](https://github.com/ipfs/js-ipfs/releases)
-
-# ❤️ Huge thank you to everyone that made this release possible
-
-In alphabetical order, here are all the humans that contributed to the release:
-
-- ...
-
-# 🙌🏽 Want to contribute?
-
-Would you like to contribute to the IPFS project and don't know how? Well, there are a few places you can get started:
-
-- Check the issues with the `help wanted` label in the [js-ipfs repo](https://github.com/ipfs/js-ipfs/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
-- Join an IPFS All Hands, introduce yourself and let us know where you would like to contribute - https://github.com/ipfs/team-mgmt/#weekly-ipfs-all-hands
-- Hack with IPFS and show us what you made! The All Hands call is also the perfect venue for demos, join in and show us what you built
-- Join the discussion at http://discuss.ipfs.io/ and help users finding their answers.
-- Join the [🚀 IPFS Core Implementations Weekly Sync 🛰](https://github.com/ipfs/team-mgmt/issues/992) and be part of the action!
-
-# ⁉️ Do you have questions?
-
-The best place to ask your questions about IPFS, how it works and what you can do with it is at [discuss.ipfs.io](http://discuss.ipfs.io). We are also available at the `#ipfs` channel on Freenode.
diff --git a/doc/config.md b/doc/config.md
deleted file mode 100644
index b1df05db22..0000000000
--- a/doc/config.md
+++ /dev/null
@@ -1,207 +0,0 @@
-# The js-ipfs config file
-
-The js-ipfs config file is a JSON document located in the root directory of the js-ipfs repository.
-
-## Table of Contents
-
-- [`Addresses`](#addresses)
- - [`API`](#api)
- - [`Delegates`](#delegates)
- - [`Gateway`](#gateway)
- - [`Swarm`](#swarm)
-- [`Bootstrap`](#bootstrap)
-- [`Datastore`](#datastore)
- - [`Spec`](#spec)
-- [`Discovery`](#discovery)
- - [`MDNS`](#mdns)
- - [`webRTCStar`](#webrtcstar)
-- [`Identity`](#identity)
- - [`PeerID`](#peerid)
- - [`PrivKey`](#privkey)
-- [`Keychain`](#keychain)
-- [`Swarm`](#swarm)
- - [`ConnMgr`](#connmgr)
-
-## `Addresses`
-Contains information about various listener addresses to be used by this node.
-
-### `API`
-
-The IPFS daemon exposes an HTTP API that allows to control the node and run the same commands as you can do from the command line. It is defined on the [HTTP API Spec](https://docs.ipfs.io/reference/api/http).
-
-[Multiaddr](https://github.com/multiformats/multiaddr/) or array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing the address(es) to serve the HTTP API on.
-
-Default: `/ip4/127.0.0.1/tcp/5002`
-
-### `Delegates`
-
-Delegate peers are used to find peers and retrieve content from the network on your behalf.
-
-Array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing which addresses to use as delegate nodes.
-
-Default: `[]`
-
-### `Gateway`
-
-A gateway is exposed by the IPFS daemon, which allows an easy way to access content from IPFS, using an IPFS path.
-
-[Multiaddr](https://github.com/multiformats/multiaddr/) or array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing the address(es) to serve the gateway on.
-
-Default: `/ip4/127.0.0.1/tcp/9090`
-
-### `Swarm`
-
-Array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing which addresses to listen on for p2p swarm connections.
-
-Default:
-```json
-[
- "/ip4/0.0.0.0/tcp/4002",
- "/ip4/127.0.0.1/tcp/4003/ws"
-]
-```
-
-## `Bootstrap`
-
-Bootstrap is an array of [Multiaddr](https://github.com/multiformats/multiaddr/) of trusted nodes to connect to in order to
-initiate a connection to the network.
-
-## `Datastore`
-
-Contains information related to the construction and operation of the on-disk storage system.
-
-### `Spec`
-
-Spec defines the structure of the IPFS datastore. It is a composable structure, where each datastore is represented by a JSON object. Datastores can wrap other datastores to provide extra functionality (e.g. metrics, logging, or caching).
-
-This can be changed manually, however, if you make any changes that require a different on-disk structure, you will need to run the [ipfs-ds-convert tool](https://github.com/ipfs/ipfs-ds-convert) to migrate data into the new structures.
-
-Default:
-```json
-{
- "mounts": [
- {
- "child": {
- "path": "blocks",
- "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
- "sync": true,
- "type": "flatfs"
- },
- "mountpoint": "/blocks",
- "prefix": "flatfs.datastore",
- "type": "measure"
- },
- {
- "child": {
- "compression": "none",
- "path": "datastore",
- "type": "levelds"
- },
- "mountpoint": "/",
- "prefix": "leveldb.datastore",
- "type": "measure"
- }
- ],
- "type": "mount"
-}
-```
-
-## `Discovery`
-
-Contains options for configuring IPFS node discovery mechanisms.
-
-### `MDNS`
-
-Multicast DNS is a discovery protocol that is able to find other peers on the local network.
-
-Options for Multicast DNS peer discovery:
-
-- `Enabled`
-
- A boolean value for whether or not MDNS should be active.
-
- Default: `true`
-
-- `Interval`
-
- A number of seconds to wait between discovery checks.
-
- Default: `10`
-
-### `webRTCStar`
-
-WebRTCStar is a discovery mechanism prvided by a signalling-star that allows peer-to-peer communications in the browser.
-
-Options for webRTCstar peer discovery:
-
-- `Enabled`
-
- A boolean value for whether or not webRTCStar should be active.
-
- Default: `true`
-
-## `Identity`
-
-### `PeerID`
-
-The unique PKI identity label for this configs peer. Set on init and never read, its merely here for convenience. IPFS will always generate the peerID from its keypair at runtime.
-
-### `PrivKey`
-
-The base64 encoded protobuf describing (and containing) the nodes private key.
-
-## `Keychain`
-
-We can customize the key management and criptographically protected messages by changing the Keychain options. Those options are used for generating the derived encryption key (`DEK`). The `DEK` object, along with the passPhrase, is the input to a PBKDF2 function.
-
-Default:
-```json
-{
- "dek": {
- "keyLength": 512/8,
- "iterationCount": 1000,
- "salt": "at least 16 characters long",
- "hash": "sha2-512"
- }
-}
-```
-
-You can check the [parameter choice for pbkdf2](https://cryptosense.com/parameter-choice-for-pbkdf2/) for more information.
-
-## `Swarm`
-
-Options for configuring the swarm.
-
-### `ConnMgr`
-
-The connection manager determines which and how many connections to keep and can be configured to keep.
-
-- `LowWater`
-
- The minimum number of connections to maintain.
-
- Default: `200` (both browser and node.js)
-
-- `HighWater`
-
- The number of connections that, when exceeded, will trigger a connection GC operation.
-
- Default: `500` (both browser and node.js)
-
-The "basic" connection manager tries to keep between `LowWater` and `HighWater` connections. It works by:
-
-1. Keeping all connections until `HighWater` connections is reached.
-2. Once `HighWater` is reached, it closes connections until `LowWater` is reached.
-
-**Example:**
-
-```json
-{
- "Swarm": {
- "ConnMgr": {
- "LowWater": 100,
- "HighWater": 200,
- }
- }
-}
-```
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
new file mode 100644
index 0000000000..d17f8a4cb5
--- /dev/null
+++ b/docs/ARCHITECTURE.md
@@ -0,0 +1,36 @@
+# IPFS Architecture
+
+## Table of Contents
+
+- [Code Architecture and folder Structure](#code-architecture-and-folder-structure)
+ - [Source code](#source-code)
+
+
+
+[Annotated version](https://user-images.githubusercontent.com/1211152/47606420-b6265780-da13-11e8-923b-b365a8534e0e.png)
+
+What does this image explain?
+
+- IPFS uses `ipfs-repo` which picks `fs` or `indexeddb` as its storage drivers, depending if it is running in Node.js or in the Browser.
+- The exchange protocol, `bitswap`, uses the Block Service which in turn uses the Repo, offering a get and put of blocks to the IPFS implementation.
+- The DAG API (previously Object) comes from the IPLD Resolver, it can support several IPLD Formats (i.e: dag-pb, dag-cbor, etc).
+- The Files API uses `ipfs-unixfs-engine` to import and export files to and from IPFS.
+- libp2p, the network stack of IPFS, uses libp2p to dial and listen for connections, to use the DHT, for discovery mechanisms, and more.
+
+## Code Architecture and folder Structure
+
+
+
+### Source code
+
+```Bash
+> tree src -L 2
+src # Main source code folder
+├── cli # Implementation of the IPFS CLI
+│ └── ...
+├── http # The HTTP-API implementation of IPFS as defined by HTTP API spec
+├── core # IPFS implementation, the core (what gets loaded in browser)
+│ ├── components # Each of IPFS subcomponent
+│ └── ...
+└── ...
+```
diff --git a/docs/BROWSERS.md b/docs/BROWSERS.md
new file mode 100644
index 0000000000..33366f26a7
--- /dev/null
+++ b/docs/BROWSERS.md
@@ -0,0 +1,81 @@
+# Using JS IPFS in the Browser
+
+## Table of Contents
+
+- [Limitations of the Browser Context](#limitations-of-the-browser-context)
+- [Addressing Limitations](#addressing-limitations)
+- [Best Practices](#best-practices)
+- [Code Examples](#code-examples)
+
+JS IPFS is the implementation of IPFS protocol in JavaScript. It can run on any
+evergreen browser, inside a service or web worker, browser extensions, Electron, and in Node.js.
+
+**This document provides key information about running JS IPFS in the browser.
+Save time and get familiar with common caveats and limitations of the browser context.**
+
+## Limitations of the Browser Context
+
+- Transport options are currently limited to [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) and [WebRTC](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API).
+
+ This means JS IPFS running in the browser is limited to Web APIs available on a web page.
+ There is no access to raw TCP sockets nor low-level UDP, only WebSockets, and WebRTC.
+
+- Key [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) require or are restricted by [Secure Context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) policies.
+
+ This means JS IPFS needs to run within Secure Context (HTTPS or localhost).
+ JS IPFS running on HTTPS website requires Secure WebSockets (TLS) and won't work with unencrypted ones.
+ [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) not being available at all.
+
+- JS IPFS comes with limited support for the [DHT](https://docs.ipfs.tech/concepts/dht/) in client mode which delegates content discovery requests to other DHT nodes.
+
+ However, it's worth noting that even though you'll get results from DHT queries, most nodes in the network are not dialable from browsers because they only support TCP and/or QUIC transports.
+
+ For now, the content discovery and connectivity to other peers are achieved with a mix of DHT client requests, rendezvous and relay servers, delegated peer/content routing, and preload servers.
+
+
+## Addressing Limitations
+
+We provide a few additional components useful for running JS IPFS in the browser:
+
+
+- [libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star) - incorporates both a transport and a discovery service that is facilitated by the custom rendezvous server available in the repo
+ - Instructions on enabling `webrtc-star` in js-ipfs config can be found [here](https://github.com/ipfs/js-ipfs/blob/master/docs/FAQ.md#how-to-enable-webrtc-support-for-js-ipfs-in-the-browser).
+ - Make sure to [run your own rendezvous server](https://github.com/libp2p/js-libp2p-webrtc-star#rendezvous-server-aka-signalling-server).
+- [libp2p-webrtc-direct](https://github.com/libp2p/js-libp2p-webrtc-direct) - a WebRTC transport that doesn't require the set up a signaling server.
+ - Caveat: you can only establish Browser to Node.js and Node.js to Node.js connections.
+
+**Note:** those are semi-centralized solutions. We are working towards replacing `*-star` with ambient relays and [libp2p-rendezvous](https://github.com/libp2p/js-libp2p-rendezvous). Details and progress can be found [here](https://github.com/libp2p/js-libp2p/issues/385).
+
+You can find detailed information about running js-ipfs [here](https://github.com/ipfs/js-ipfs#table-of-contents).
+
+## Best Practices
+
+- Configure nodes for using self-hosted `*-star` signalling and transport service. When in doubt, use WebSockets ones.
+- Run your own instance of `*-star` signalling service.
+ The default ones are under high load and should be used only for tests and development.
+- Make sure content added to js-ipfs running in the browser is persisted/cached somewhere on a regular long-running IPFS daemon, e.g. [kubo](https://github.com/ipfs/kubo/)
+ - Manually `pin` or preload CIDs of interest with `refs -r` beforehand.
+ - Preload content on the fly using [preload](https://github.com/ipfs/js-ipfs/blob/master/docs/MODULE.md#optionspreload) feature and/or
+ configure [delegated routing](https://github.com/ipfs/js-ipfs/blob/master/docs/DELEGATE_ROUTERS.md).
+ - Avoid public instances in production environments. Make sure preload and delegate nodes used in config are self-hosted and under your control (expose a subset of [kubo](https://github.com/ipfs/kubo/) (formerly go-ipfs) APIs via reverse proxy such as Nginx).
+- If your main goal is to provide content and files to the IPFS network from a browser and you would like to avoid running infrastructure, consider using a pinning service like [Web3.storage](https://web3.storage/).
+
+## Code Examples
+
+Prebuilt bundles are available, using JS IPFS in the browser is as simple as:
+
+```js
+
+
+```
+
+More advanced examples and tutorials can be found in the [examples](https://github.com/ipfs-examples)
diff --git a/docs/CLI.md b/docs/CLI.md
new file mode 100644
index 0000000000..f75da036ec
--- /dev/null
+++ b/docs/CLI.md
@@ -0,0 +1,39 @@
+# IPFS CLI
+
+## Table of contents
+
+- [Overview](#overview)
+- [Configuration](#configuration)
+
+## Overview
+
+In order to use js-ipfs as a CLI, you must install it with the `global` flag. Run the following (even if you have ipfs installed locally):
+
+```bash
+npm install ipfs --global
+```
+
+The CLI is available by using the command `jsipfs` in your terminal. This is aliased, instead of using `ipfs`, to make sure it does not conflict with the [Go implementation](https://github.com/ipfs/go-ipfs).
+
+Once installed, please follow the [Getting Started Guide](https://docs.ipfs.io/introduction/usage/) to learn how to initialize your node and run the daemon.
+
+```sh
+# Install js-ipfs globally
+> jsipfs --help
+Commands:
+ bitswap A set of commands to manipulate the bitswap agent.
+ block Manipulate raw IPFS blocks.
+ bootstrap Show or edit the list of bootstrap peers.
+ commands List all available commands
+ config [value] Get and set IPFS config values
+ daemon Start a long-running daemon process
+# ...
+```
+
+## Configuration
+
+`js-ipfs` uses some different default config values, so that they don't clash directly with a go-ipfs node running in the same machine. These are:
+
+- default repo location: `~/.jsipfs` (can be changed with env variable `IPFS_PATH`)
+- default swarm port: `4002`
+- default API port: `5002`
diff --git a/docs/CONFIG.md b/docs/CONFIG.md
new file mode 100644
index 0000000000..546d9d1ddf
--- /dev/null
+++ b/docs/CONFIG.md
@@ -0,0 +1,352 @@
+# The js-ipfs config file
+
+The js-ipfs config file is a JSON document located in the root directory of the js-ipfs repository.
+
+## Table of Contents
+
+- [Profiles](#profiles)
+- [`Addresses`](#addresses)
+ - [`API`](#api)
+ - [`RPC`](#rpc)
+ - [`Delegates`](#delegates)
+ - [`Gateway`](#gateway)
+ - [`Swarm`](#swarm)
+ - [`Announce`](#announce)
+- [`Bootstrap`](#bootstrap)
+- [`Datastore`](#datastore)
+ - [`Spec`](#spec)
+- [`Discovery`](#discovery)
+ - [`MDNS`](#mdns)
+ - [`webRTCStar`](#webrtcstar)
+- [`Identity`](#identity)
+ - [`PeerID`](#peerid)
+ - [`PrivKey`](#privkey)
+- [`Keychain`](#keychain)
+- [`Pubsub`](#pubsub)
+ - [`Router`](#router)
+ - [`Enabled`](#enabled)
+- [`Swarm`](#swarm-1)
+ - [`ConnMgr`](#connmgr)
+ - [`DisableNatPortMap`](#disablenatportmap)
+ - [Example](#example)
+- [`API`](#api-1)
+ - [`HTTPHeaders`](#httpheaders)
+ - [`Access-Control-Allow-Origin`](#access-control-allow-origin)
+ - [Example](#example-1)
+ - [`Access-Control-Allow-Credentials`](#access-control-allow-credentials)
+ - [Example](#example-2)
+
+## Profiles
+
+Configuration profiles allow to tweak configuration quickly. Profiles can be
+applied with `--profile` flag to `ipfs init` or with the `ipfs config profile
+apply` command. When a profile is applied a backup of the configuration file
+will be created in `$IPFS_PATH`.
+
+Available profiles:
+
+- `server`
+
+ Recommended for nodes with public IPv4 address (servers, VPSes, etc.),
+ disables host and content discovery in local networks.
+
+- `local-discovery`
+
+ Sets default values to fields affected by `server` profile, enables
+ discovery in local networks.
+
+- `test`
+
+ Reduces external interference, useful for running ipfs in test environments.
+ Note that with these settings node won't be able to talk to the rest of the
+ network without manual bootstrap.
+
+- `default-networking`
+
+ Restores default network settings. Inverse profile of the `test` profile.
+
+- `lowpower`
+
+ Reduces daemon overhead on the system. May affect node functionality,
+ performance of content discovery and data fetching may be degraded.
+
+- `default-power`
+
+ Inverse of "lowpower" profile.
+
+## `Addresses`
+
+Contains information about various listener addresses to be used by this node.
+
+### `API`
+
+The IPFS daemon exposes an HTTP API that allows to control the node and run the same commands as you can do from the command line. It is defined on the [HTTP API Spec](https://docs.ipfs.io/reference/api/http).
+
+[Multiaddr](https://github.com/multiformats/multiaddr/) or array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing the address(es) to serve the HTTP API on.
+
+Default: `/ip4/127.0.0.1/tcp/5002`
+
+### `RPC`
+
+js-IPFS has a gRPC-over-websockets server that allows it to do things that you cannot do over HTTP like bi-directional streaming. It implements the same API as the [HTTP API Spec](https://docs.ipfs.io/reference/api/http) and can be accessed using the [ipfs-client](https://www.npmjs.com/package/ipfs-client) module.
+
+Configure the address it listens on using this config key.
+
+Default: `/ip4/127.0.0.1/tcp/5003`
+
+### `Delegates`
+
+Delegate peers are used to find peers and retrieve content from the network on your behalf.
+
+Array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing which addresses to use as delegate nodes.
+
+Default: `[]`
+
+### `Gateway`
+
+A gateway is exposed by the IPFS daemon, which allows an easy way to access content from IPFS, using an IPFS path.
+
+[Multiaddr](https://github.com/multiformats/multiaddr/) or array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing the address(es) to serve the gateway on.
+
+Default: `/ip4/127.0.0.1/tcp/9090`
+
+### `Swarm`
+
+Array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing which addresses to listen on for p2p swarm connections.
+
+Default:
+```json
+[
+ "/ip4/0.0.0.0/tcp/4002",
+ "/ip4/127.0.0.1/tcp/4003/ws"
+]
+```
+
+### `Announce`
+
+Array of [Multiaddr](https://github.com/multiformats/multiaddr/) describing which addresses to [announce](https://github.com/libp2p/js-libp2p/tree/master/src/address-manager#announce-addresses) over the network.
+
+Default:
+```json
+[]
+```
+
+## `Bootstrap`
+
+Bootstrap is an array of [Multiaddr](https://github.com/multiformats/multiaddr/) of trusted nodes to connect to in order to
+initiate a connection to the network.
+
+## `Datastore`
+
+Contains information related to the construction and operation of the on-disk storage system.
+
+### `Spec`
+
+Spec defines the structure of the IPFS datastore. It is a composable structure, where each datastore is represented by a JSON object. Datastores can wrap other datastores to provide extra functionality (e.g. metrics, logging, or caching).
+
+This can be changed manually, however, if you make any changes that require a different on-disk structure, you will need to run the [ipfs-ds-convert tool](https://github.com/ipfs/ipfs-ds-convert) to migrate data into the new structures.
+
+Default:
+```json
+{
+ "mounts": [
+ {
+ "child": {
+ "path": "blocks",
+ "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
+ "sync": true,
+ "type": "flatfs"
+ },
+ "mountpoint": "/blocks",
+ "prefix": "flatfs.datastore",
+ "type": "measure"
+ },
+ {
+ "child": {
+ "compression": "none",
+ "path": "datastore",
+ "type": "levelds"
+ },
+ "mountpoint": "/",
+ "prefix": "leveldb.datastore",
+ "type": "measure"
+ }
+ ],
+ "type": "mount"
+}
+```
+
+## `Discovery`
+
+Contains options for configuring IPFS node discovery mechanisms.
+
+### `MDNS`
+
+Multicast DNS is a discovery protocol that is able to find other peers on the local network.
+
+Options for Multicast DNS peer discovery:
+
+- `Enabled`
+
+ A boolean value for whether or not MDNS should be active.
+
+ Default: `true`
+
+- `Interval`
+
+ A number of seconds to wait between discovery checks.
+
+ Default: `10`
+
+### `webRTCStar`
+
+WebRTCStar is a discovery mechanism provided by a signalling-star that allows peer-to-peer communications in the browser.
+
+Options for webRTCstar peer discovery:
+
+- `Enabled`
+
+ A boolean value for whether or not webRTCStar should be active.
+
+ Default: `true`
+
+## `Identity`
+
+### `PeerID`
+
+The unique PKI identity label for this configs peer. Set on init and never read, its merely here for convenience. IPFS will always generate the peerID from its keypair at runtime.
+
+### `PrivKey`
+
+The base64 encoded protobuf describing (and containing) the nodes private key.
+
+## `Keychain`
+
+We can customize the key management and cryptographically protected messages by changing the Keychain options. Those options are used for generating the derived encryption key (`DEK`). The `DEK` object, along with the passPhrase, is the input to a PBKDF2 function.
+
+Default:
+```json
+{
+ "dek": {
+ "keyLength": 512/8,
+ "iterationCount": 1000,
+ "salt": "at least 16 characters long",
+ "hash": "sha2-512"
+ }
+}
+```
+
+You can check the [parameter choice for pbkdf2](https://cryptosense.com/parameter-choice-for-pbkdf2/) for more information.
+
+## `Pubsub`
+
+Options for configuring the pubsub subsystem. It is important pointing out that this is not supported in the browser. If you want to configure a different pubsub router in the browser you must configure `libp2p.modules.pubsub` options instead.
+
+### `Router`
+
+A string value for specifying which pubsub routing protocol to use. You can either use `gossipsub` in order to use the [ChainSafe/gossipsub-js](https://github.com/ChainSafe/gossipsub-js) implementation, or `floodsub` to use the [libp2p/js-libp2p-floodsub](https://github.com/libp2p/js-libp2p-floodsub) implementation. You can read more about these implementations on the [libp2p/specs/pubsub](https://github.com/libp2p/specs/tree/master/pubsub) document.
+
+Default: `gossipsub`
+
+### `Enabled`
+
+A boolean value for wether or not pubsub router should be active.
+
+Default: `true`
+
+## `Swarm`
+
+Options for configuring the swarm.
+
+### `ConnMgr`
+
+The connection manager determines which and how many connections to keep and can be configured to keep.
+
+- `LowWater`
+
+ The minimum number of connections to maintain.
+
+ Default: `200` (both browser and node.js)
+
+- `HighWater`
+
+ The number of connections that, when exceeded, will trigger a connection GC operation.
+
+ Default: `500` (both browser and node.js)
+
+The "basic" connection manager tries to keep between `LowWater` and `HighWater` connections. It works by:
+
+1. Keeping all connections until `HighWater` connections is reached.
+2. Once `HighWater` is reached, it closes connections until `LowWater` is reached.
+
+### `DisableNatPortMap`
+
+By default when running under nodejs, libp2p will try to use [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play) to open a random high port on your router for any TCP connections you have configured.
+
+Set `DisableNatPortMap` to `false` to disable this behaviour.
+
+### Example
+
+```json
+{
+ "Swarm": {
+ "ConnMgr": {
+ "LowWater": 100,
+ "HighWater": 200,
+ }
+ },
+ "DisableNatPortMap": false
+}
+```
+
+## `API`
+
+Settings applied to the HTTP RPC API server
+
+### `HTTPHeaders`
+
+HTTP header settings used by the HTTP RPC API server
+
+#### `Access-Control-Allow-Origin`
+
+The RPC API endpoints running on your local node are protected by the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) mechanism.
+
+When a request is made that sends an `Origin` header, that Origin must be present in the allowed origins configured for the node, otherwise the browser will disallow that request to proceed, unless `mode: 'no-cors'` is set on the request, in which case the response will be opaque.
+
+To allow requests from web browsers, configure the `API.HTTPHeaders.Access-Control-Allow-Origin` setting. This is an array of URL strings with safelisted Origins.
+
+##### Example
+
+If you are running a webapp locally that you access via the URL `http://127.0.0.1:3000`, you must add it to the list of allowed origins in order to make API requests from that webapp in the browser:
+
+```json
+{
+ "API": {
+ "HTTPHeaders": {
+ "Access-Control-Allow-Origin": [
+ "http://127.0.0.1:3000"
+ ]
+ }
+ }
+}
+```
+
+Note that the origin must match exactly so `'http://127.0.0.1:3000'` is treated differently to `'http://127.0.0.1:3000/'`
+
+#### `Access-Control-Allow-Credentials`
+
+The [Access-Control-Allow-Credentials](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) header allows client-side JavaScript running in the browser to send and receive credentials with requests - cookies, auth headers or TLS certificates.
+
+For most applications this will not be necessary but if you require this to be set, see the example below for how to configure it.
+
+##### Example
+
+```json
+{
+ "API": {
+ "HTTPHeaders": {
+ "Access-Control-Allow-Credentials": true
+ }
+ }
+}
+```
diff --git a/docs/CORS.md b/docs/CORS.md
new file mode 100644
index 0000000000..d08a5b89c1
--- /dev/null
+++ b/docs/CORS.md
@@ -0,0 +1,23 @@
+# CORS
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Configure CORS headers](#configure-cors-headers)
+
+## Overview
+
+Cross-origin Resource Sharing is a browser security mechanism that prevents unauthorized scripts from accessing resources from different domains.
+
+By default the HTTP RPC API of js-IPFS will cause any request sent from a CORS-respecting browser to fail.
+
+## Configure CORS headers
+
+You can configure your node to allow requests from other domains to proceed by setting the appropriate headers in the node config:
+
+```console
+$ jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://example.com"]'
+$ jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST", "GET"]'
+```
+
+Restart the daemon for the settings to take effect.
diff --git a/docs/DAEMON.md b/docs/DAEMON.md
new file mode 100644
index 0000000000..febd011eb7
--- /dev/null
+++ b/docs/DAEMON.md
@@ -0,0 +1,35 @@
+
+# Running IPFS as a daemon
+
+> How to run a long-lived IPFS process
+
+## Table of contents
+
+- [CLI](#cli)
+- [Programmatic](#programmatic)
+
+## CLI
+
+To start a daemon on the CLI, use the `daemon` command:
+
+```console
+jsipfs daemon
+```
+
+The IPFS Daemon exposes the API defined in the [HTTP API spec](https://docs.ipfs.io/reference/api/http/). You can use any of the IPFS HTTP-API client libraries with it, such as: [ipfs-http-client](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client).
+
+## Programmatic
+
+If you want a programmatic way to spawn a IPFS Daemon using JavaScript, check out the [ipfsd-ctl](https://github.com/ipfs/js-ipfsd-ctl) module.
+
+```javascript
+import { createFactory } from 'ipfsd-ctl'
+const factory = createFactory({
+ type: 'proc' // or 'js' to run in a separate process
+})
+
+const node = await factory.create()
+
+// print the node ide
+console.info(await node.id())
+```
diff --git a/docs/DELEGATE_ROUTERS.md b/docs/DELEGATE_ROUTERS.md
new file mode 100644
index 0000000000..03b906a6c0
--- /dev/null
+++ b/docs/DELEGATE_ROUTERS.md
@@ -0,0 +1,30 @@
+# Configuring Delegate Routers
+
+- [What is it?](#what-is-it)
+- [How do I do it?](#how-do-i-do-it)
+
+## What is it?
+
+Delegate routers perform tasks on behalf of nodes that may be missing functionality, so for example they may search the DHT for peers or content providers on behalf of IPFS implementations that do not have a DHT.
+
+The delegate node is started and the client of the delegate calls API methods using the IPFS HTTP API client.
+
+## How do I do it?
+
+If you need to support Delegated Content and/or Peer Routing, you can enable it by specifying the multiaddrs of your delegate nodes in the config via `options.config.Addresses.Delegates`. If you need to run a delegate router we encourage you to run your own, with go-ipfs. You can see instructions for doing so in the [delegated routing example](https://github.com/libp2p/js-libp2p/tree/master/examples/delegated-routing).
+
+If you are not able to run your own delegate router nodes, we currently have two nodes that support delegated routing. **Important**: As many people may be leveraging these nodes, performance may be affected, which is why we recommend running your own nodes in production.
+
+Available delegate multiaddrs are:
+
+- `/dns4/node0.delegate.ipfs.io/tcp/443/https`
+- `/dns4/node1.delegate.ipfs.io/tcp/443/https`
+- `/dns4/node2.delegate.ipfs.io/tcp/443/https`
+- `/dns4/node3.delegate.ipfs.io/tcp/443/https`
+
+**Note**: If more than 1 delegate multiaddr is specified, the actual delegate will be randomly selected on startup.
+
+**Note**: If you wish to use delegated routing and are creating your node _programmatically_ in Node.js or the browser you must `npm install libp2p-delegated-content-routing` and/or `npm install libp2p-delegated-peer-routing` and provide configured instances of them in [`options.libp2p`](./MODULE.md#optionslibp2p). See the module repos for further instructions:
+
+- https://github.com/libp2p/js-libp2p-delegated-content-routing
+- https://github.com/libp2p/js-libp2p-delegated-peer-routing
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
new file mode 100644
index 0000000000..6ac3a4f7d9
--- /dev/null
+++ b/docs/DEVELOPMENT.md
@@ -0,0 +1,128 @@
+# Development
+
+> Getting started with development on IPFS
+
+- [Install npm@7](#install-npm7)
+- [Clone and install dependencies](#clone-and-install-dependencies)
+- [Run tests](#run-tests)
+- [Lint](#lint)
+- [Build types and minified browser bundles](#build-types-and-minified-browser-bundles)
+- [Publishing new versions](#publishing-new-versions)
+- [Using prerelease versions](#using-prerelease-versions)
+- [Testing strategy](#testing-strategy)
+ - [CLI](#cli)
+ - [HTTP API](#http-api)
+ - [Core](#core)
+ - [Non-Core](#non-core)
+
+## Install npm@7
+
+This project uses a [workspace](https://docs.npmjs.com/cli/v7/using-npm/workspaces) structure so requires npm@7 or above. If you are running node 15 or later you already have it, if not run:
+
+```sh
+$ npm install -g npm@latest
+```
+
+## Clone and install dependencies
+
+```sh
+> git clone https://github.com/ipfs/js-ipfs.git
+> cd js-ipfs
+> npm install
+```
+
+This will install [lerna](https://www.npmjs.com/package/lerna) and bootstrap the various packages, deduping and hoisting dependencies into the root folder.
+
+If later you add new dependencies to submodules or just wish to remove all the `node_modules`/`dist` folders and start again, run `npm run reset && npm install` from the root.
+
+See the scripts section of the root [`package.json`](../package.json) for more commands.
+
+## Run tests
+
+```sh
+# run all the unit tests
+> npm test
+
+# run individual tests (findprovs)
+> npm run test -- --grep findprovs
+
+# run just IPFS tests in Node.js
+> npm run test -- -- -- -t node
+
+# run just IPFS tests in a headless browser
+> npm run test -- -- -- -t browser
+
+# run the interface tests against ipfs-core
+> npm run test:interface:core
+
+# run the interface tests over HTTP against js-ipfs
+> npm run test:interface:http-js
+
+# run the interface tests over HTTP against go-ipfs from a browser
+> npm run test:interface:http-go -- -- -- -t browser
+
+# run the interop tests against js-ipfs and go-ipfs on the Electron main process
+> npm run test:interop -- -- -- -t electron-main
+```
+
+More granular test suites can be run from each submodule.
+
+Please see the `package.json` in each submodule for available commands.
+
+## Lint
+
+Please run the linter before submitting a PR, the build will not pass if it fails:
+
+```sh
+> npm run lint
+```
+
+## Build types and minified browser bundles
+
+```sh
+> npm run build
+```
+
+## Publishing new versions
+
+1. Ensure you have a `GH_TOKEN` env var containing a GitHub [Personal Access Token](https://github.com/settings/tokens) with `public_repo` permissions
+2. You'll also need a valid [Docker Hub](https://hub.docker.com) login with sufficient permissions to publish new Docker images to the [ipfs/js-ipfs](https://hub.docker.com/repository/docker/ipfs/js-ipfs) repository
+3. From the root of this repo run `npm run release` and follow the on screen prompts. It will use [conventional commits](https://www.conventionalcommits.org) to work out the new package version
+
+## Using prerelease versions
+
+Any changed packages from each successful build of master are published to npm as canary builds under the npm tag `next`.
+
+## Testing strategy
+
+This project has a number of components that have their own tests, then some components that share interface tests.
+
+When adding new features you may need to add tests to one or more of the test suites described below.
+
+### CLI
+
+Tests live in [/packages/ipfs/test/cli](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/test/cli).
+
+All interactions with IPFS core are stubbed so we just ensure that the correct arguments are passed in
+
+### HTTP API
+
+Tests live in [/packages/ipfs/test/http-api](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/test/http-api) and are similar to the CLI tests in that we stub out core interactions and inject requests with [shot](https://www.npmjs.com/package/@hapi/shot).
+
+### Core
+
+Anything non-implementation specific should be considered part of the 'Core API'. For example node setup code is not Core, but anything that does useful work, e.g. network/repo/etc interactions would be Core.
+
+All Core APIs should be documented in [/docs/core-api](https://github.com/ipfs/js-ipfs/tree/master/docs/core-api).
+
+All Core APIs should have comprehensive tests in [/packages/interface-ipfs-core](https://github.com/ipfs/js-ipfs/tree/master/packages/interface-ipfs-core).
+
+`interface-ipfs-core` should ensure API compatibility across implementations. Tests are run:
+
+1. Against [/packages/ipfs/src/core](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/core) directly
+1. Against [/packages/ipfs/src/http](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/src/http) over HTTP via `ipfs-http-client`
+1. Against `go-ipfs` over HTTP via `ipfs-http-client`
+
+### Non-Core
+
+Any non-core API functionality should have tests in the `tests` directory of the module in question, for example: [/packages/ipfs-http-api/tests](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client/test) and [/packages/ipfs/tests](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs/test) for `ipfs-http-client` and `ipfs` respectively.
diff --git a/docs/DOCKER.md b/docs/DOCKER.md
new file mode 100644
index 0000000000..551336c05b
--- /dev/null
+++ b/docs/DOCKER.md
@@ -0,0 +1,32 @@
+
+# Running js-ipfs with Docker
+
+We have automatic Docker builds setup with Docker Hub: https://hub.docker.com/r/ipfs/js-ipfs/
+
+All branches in the Github repository maps to a tag in Docker Hub, except `master` Git branch which is mapped to `latest` Docker tag.
+
+You can run js-ipfs like this:
+
+```
+$ docker run -it -p 4002:4002 -p 4003:4003 -p 5002:5002 -p 9090:9090 ipfs/js-ipfs:latest
+
+initializing ipfs node at /root/.jsipfs
+generating 2048-bit RSA keypair...done
+peer identity: Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
+to get started, enter:
+
+ jsipfs files cat /ipfs/QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr/readme
+
+Initializing daemon...
+Using wrtc for webrtc support
+Swarm listening on /ip4/127.0.0.1/tcp/4003/ws/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
+Swarm listening on /ip4/172.17.0.2/tcp/4003/ws/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
+Swarm listening on /ip4/127.0.0.1/tcp/4002/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
+Swarm listening on /ip4/172.17.0.2/tcp/4002/ipfs/Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS
+API is listening on: /ip4/0.0.0.0/tcp/5002
+Gateway (readonly) is listening on: /ip4/0.0.0.0/tcp/9090
+Daemon is ready
+
+$ curl --silent localhost:5002/api/v0/id | jq .ID
+"Qmbd5jx8YF1QLhvwfLbCTWXGyZLyEJHrPbtbpRESvYs4FS"
+```
diff --git a/docs/EARLY_TESTERS.md b/docs/EARLY_TESTERS.md
new file mode 100644
index 0000000000..f1cc5b0e27
--- /dev/null
+++ b/docs/EARLY_TESTERS.md
@@ -0,0 +1,38 @@
+# Early Testers Programme
+
+- [What is it?](#what-is-it)
+- [What are the expectations?](#what-are-the-expectations)
+- [Who has signed up?](#who-has-signed-up)
+- [How to sign up?](#how-to-sign-up)
+
+## What is it?
+
+The early testers programme allows groups using js-ipfs in production to self-volunteer to help test js-ipfs release candidates to ensure that no regressions that might affect production systems make it into the final release. While we invite the _entire_ community to help test releases, members of the early testers program are expected to participate directly and actively in every release.
+
+## What are the expectations?
+
+Members of the early tester program are expected to work closely with us to:
+
+* Provide high quality, actionable feedback.
+* Work directly with us to debug regressions in the release.
+* Help ensure a rock-solid, timely release.
+
+We will ask early testers to participate at two points in the process:
+
+* When js-ipfs enters the second release stage, early testers will be asked to test js-ipfs on non-production infrastructure. This may involve things like:
+ - Running integration tests against the release candidate.
+ - Running simulations/benchmarks on the release candidate.
+ - Manually testing the release candidate to check for regressions.
+* When js-ipfs enters the third release stage (soft release), early testers will be asked to partially deploy the release candidate to production infrastructure. Release candidates at this stage are expected to be identical to the final release. However, this stage allows the js-ipfs team to fix any last-minute regressions without cutting an entirely new release.
+
+## Who has signed up?
+
+- [npm-on-ipfs](https://github.com/ipfs-shipyard/npm-on-ipfs) - install your dependencies via the distributed web!
+- [orbit-db](https://github.com/orbitdb/orbit-db) - Peer-to-Peer Databases for the Decentralized Web
+- [ipfs-log](https://github.com/orbitdb/ipfs-log) - Append-only log CRDT on IPFS
+- [Sidetree DID Protocol](https://github.com/decentralized-identity/sidetree) - Decentralized Identifier Layer-2 network protocol
+- [Constellation](https://julienmalard.github.io/constellation/) - Distributed scientific databases for citizen science and more
+
+## How to sign up?
+
+Simply submit a PR to this document by adding your project name and contact.
diff --git a/docs/FAQ.md b/docs/FAQ.md
new file mode 100644
index 0000000000..c7b314cb5d
--- /dev/null
+++ b/docs/FAQ.md
@@ -0,0 +1,177 @@
+# FAQ
+
+## Table of Contents
+
+- [Why isn't there DHT support in js-IPFS?](#why-isnt-there-dht-support-in-js-ipfs)
+ - [Node.js](#nodejs)
+ - [Browser](#browser)
+- [How to enable WebRTC support for js-ipfs in the Browser](#how-to-enable-webrtc-support-for-js-ipfs-in-the-browser)
+- [Is there WebRTC support for js-ipfs with Node.js?](#is-there-webrtc-support-for-js-ipfs-with-nodejs)
+- [How can I configure an IPFS node to use a custom `signaling endpoint` for my WebRTC transport?](#how-can-i-configure-an-ipfs-node-to-use-a-custom-signaling-endpoint-for-my-webrtc-transport)
+- [I see some slowness when hopping between tabs Chrome with IPFS nodes, is there a reason why?](#i-see-some-slowness-when-hopping-between-tabs-chrome-with-ipfs-nodes-is-there-a-reason-why)
+- [Can I use IPFS in my Electron App?](#can-i-use-ipfs-in-my-electron-app)
+- [What are all these `refs?Qmfoo` HTTP errors I keep seeing in the console?](#what-are-all-these-refsqmfoo-http-errors-i-keep-seeing-in-the-console)
+- [Have more questions?](#have-more-questions)
+
+## Why isn't there DHT support in js-IPFS?
+
+There is DHT support for js-IPFS in the form of [libp2p/js-libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) but it is not finished yet, and may not be the right solution to the problem.
+
+### Node.js
+
+To enable DHT support, before starting your daemon run:
+
+```console
+$ jsipfs config Routing.Type dht
+```
+
+The possible values for `Routing.Type` are:
+
+ - `'none'` the default, this means the DHT is turned off any you must manually dial other nodes
+ - `'dht'` start the node in DHT client mode, if it is discovered to be publicly dialable it will automatically switch to server mode
+ - `'dhtclient'` A DHT client is able to make DHT queries but will not respond to any
+ - `'dhtserver'` A DHT server can make and respond to DHT queries. Please only choose this option if your node is dialable from the open Internet.
+
+At the time of writing, only DHT client mode is supported and will be selected if `Routing.Type` is not `'none'`.
+
+### Browser
+
+In the browser there are many constraints that mean the environment does not typically make for good DHT participants - the number of connections required is high, people do not tend to stay on a page for long enough to make or answer DHT queries, and even if they did, most nodes on the network talk TCP - the browser can neither open TCP ports on remote hosts nor accept TCP connections.
+
+A better approach may be to set up [Delegate Routing](./DELEGATE_ROUTERS.md) to use remote go-IPFS to make queries on the browsers' behalf as these do not have the same constraints.
+
+Of course, there's no reason why js on the server should not be a fully fledged DHT participant, please help out on the [libp2p/js-libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) repo to make this a reality!
+
+## How to enable WebRTC support for js-ipfs in the Browser
+
+To add a WebRTC transport to your js-ipfs node, you must add a WebRTC multiaddr. To do that, simple override the config.Addresses.Swarm array which contains all the multiaddrs which the IPFS node will use. See below:
+
+```JavaScript
+const node = await IPFS.create({
+ config: {
+ Addresses: {
+ Swarm: [
+ '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
+ '/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
+ ]
+ }
+ }
+})
+
+// your instance with WebRTC is ready
+```
+
+**Important:** This transport usage is kind of unstable and several users have experienced crashes. Track development of a solution at https://github.com/ipfs/js-ipfs/issues/1088.
+
+## Is there WebRTC support for js-ipfs with Node.js?
+
+Yes, however, bear in mind that there isn't a 100% stable solution to use WebRTC in Node.js, use it at your own risk. The most tested options are:
+
+- [wrtc](https://npmjs.org/wrtc) - Follow the install instructions.
+- [electron-webrtc](https://npmjs.org/electron-webrtc)
+
+To add WebRTC support in a IPFS node instance, do:
+
+```JavaScript
+import wrtc from 'wrtc' // or 'electron-webrtc'
+import WebRTCStar from '@libp2p/webrtc-star'
+
+const node = await IPFS.create({
+ repo: 'your-repo-path',
+ config: {
+ Addresses: {
+ Swarm: [
+ "/ip4/0.0.0.0/tcp/4002",
+ "/ip4/127.0.0.1/tcp/4003/ws",
+ "/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star",
+ "/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star"
+ ]
+ }
+ },
+ libp2p: {
+ modules: {
+ transport: [WebRTCStar]
+ },
+ config: {
+ peerDiscovery: {
+ webRTCStar: { // <- note the lower-case w - see https://github.com/libp2p/js-libp2p/issues/576
+ enabled: true
+ }
+ },
+ transport: {
+ WebRTCStar: { // <- note the upper-case w- see https://github.com/libp2p/js-libp2p/issues/576
+ wrtc
+ }
+ }
+ }
+ }
+})
+
+// your instance with WebRTC is ready
+```
+
+To add WebRTC support to the IPFS daemon, you only need to install one of the WebRTC modules globally:
+
+```bash
+npm install wrtc --global
+# or
+npm install electron-webrtc --global
+```
+
+Then, update your IPFS Daemon config to include the multiaddr for this new transport on the `Addresses.Swarm` array. Add: `"/dns4/wrtc-star.discovery.libp2p.io/wss/p2p-webrtc-star"`
+
+## How can I configure an IPFS node to use a custom `signaling endpoint` for my WebRTC transport?
+
+You'll need to execute a compatible `signaling server` ([libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star) works) and include the correct configuration param for your IPFS node:
+
+- provide the [`multiaddr`](https://github.com/multiformats/multiaddr) for the `signaling server`
+
+```JavaScript
+const node = await IPFS.create({
+ repo: 'your-repo-path',
+ config: {
+ Addresses: {
+ Swarm: [
+ '/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star'
+ ]
+ }
+ }
+})
+```
+
+The code above assumes you are running a local `signaling server` on port `9090`. Provide the correct values accordingly.
+
+## I see some slowness when hopping between tabs Chrome with IPFS nodes, is there a reason why?
+
+Yes, unfortunately, due to [Chrome aggressive resource throttling policy](https://github.com/ipfs/js-ipfs/issues/611), it cuts freezes the execution of any background tab, turning an IPFS node that was running on that webpage into a vegetable state.
+
+A way to mitigate this in Chrome, is to run your IPFS node inside a Service Worker, so that the IPFS instance runs in a background process. You can learn how to install an IPFS node as a service worker in here the repo [ipfs-service-worker](https://github.com/ipfs/ipfs-service-worker)
+
+## Can I use IPFS in my Electron App?
+
+Yes you can and in many ways. Read https://github.com/ipfs/notes/issues/256 for the multiple options.
+
+We now support Electron v5.0.0 without the need to rebuilt native modules.
+Still if you run into problems with native modules follow these instructions [here](https://electronjs.org/docs/tutorial/using-native-node-modules).
+
+## What are all these `refs?Qmfoo` HTTP errors I keep seeing in the console?
+
+In order for content added to your node to be accessible to other nodes on the network, they need to be able to [dial](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/SWARM.md#ipfsswarmconnectaddr-options) your node. This means there needs to be some way of connecting to you from the open Internet.
+
+From node.js and Electron this might be done by opening a TCP port on your router and forwarding traffic to your node, while also configuring an [Announce](https://github.com/ipfs/js-ipfs/blob/master/docs/CONFIG.md#announce) address that is a combination of the forwarded port and your public IP address.
+
+Browsers [can't open TCP sockets](https://github.com/ipfs/js-ipfs/blob/master/docs/BROWSERS.md#limitations-of-the-browser-context) so the only way right now is for your node to be connected to a WebRTC-Star signalling server - nodes interested in your content would connect to the same WebRTC-Star server and use that to negotiate a peer-to-peer connection.
+
+This has several drawbacks - WebRTC is expensive so having lots of peers does not scale well, the maximum packet size is small so it's comparatively inefficient, browsers will frequently cull connections if you switch away from the tab and at the time of writing go-IPFS [has no WebRTC-Star transport](https://libp2p.io/implementations/#transports) so great swathes of the network will not be able to dial your node.
+
+To make your content available, several 'preload' nodes are running. These nodes expose their [refs endpoint](https://docs.ipfs.io/reference/http/api/#api-v0-refs) over HTTP and all js-IPFS nodes connect to them as peers on startup.
+
+When you add content to your node, a request is sent to a preload node with the CID of the content you've just added. This causes the preload node to use [Bitswap](https://docs.ipfs.io/concepts/bitswap/) to pull the content from your node, caching it for an hour or so which then means other nodes can then access the content without having to dial your otherwise undialable node.
+
+These nodes sometimes go down, which is why you see errors in the console. They are non-fatal and can be ignored.
+
+If you run your own node you can [disable preloading](https://github.com/ipfs/js-ipfs/blob/master/docs/MODULE.md#optionspreload) which will make the errors go away, at the cost of your content becoming less available or not available at all.
+
+## Have more questions?
+
+Ask for help in our forum at https://discuss.ipfs.io or in IRC (#ipfs on Freenode).
diff --git a/docs/IPLD.md b/docs/IPLD.md
new file mode 100644
index 0000000000..8f3fcfaae4
--- /dev/null
+++ b/docs/IPLD.md
@@ -0,0 +1,146 @@
+# IPLD Codecs
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Bundled BlockCodecs](#bundled-blockcodecs)
+- [Bundled Multihashes](#bundled-multihashes)
+- [Bundled Multibases](#bundled-multibases)
+- [Adding additional BlockCodecs, Multihashes and Multibases](#adding-additional-blockcodecs-multihashes-and-multibases)
+- [Next steps](#next-steps)
+
+## Overview
+
+The IPFS repo contains a blockstore that holds the data that makes up the files on the IPFS network. These blocks can be thought of as a [CID][] and associated byte array.
+
+The [CID][] contains a `code` property that lets us know how to interpret the byte array associated with it.
+
+In order to perform that interpretation, a [BlockCodec][] must be loaded that corresponds to the `code` property of the [CID][].
+
+Similarly implementations of [Multihash][]es or [Multibase][]s must be available to be used.
+
+## Bundled BlockCodecs
+
+js-IPFS ships with four bundled codecs, the ones that are required to create and interpret [UnixFS][] structures.
+
+These are:
+
+1. [@ipld/dag-pb](https://github.com/ipld/js-dag-pb) - used for file and directory structures
+2. [raw](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/raw.js) - used for file data where imported with `--raw-leaves=true`
+3. [@ipld/dag-cbor](https://github.com/ipld/js-dag-cbor) - used for storage of JavaScript Objects with [CID] links to other blocks
+4. [json](https://github.com/multiformats/js-multiformats/blob/master/src/codecs/json.js) - used for storage of plain JavaScript Objects
+
+## Bundled Multihashes
+
+js-IPFS ships with all multihashes [exported by js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/hashes), including `sha2-256` and others.
+
+Additional hashers can be configured using the `hashers` config property.
+
+## Bundled Multibases
+
+js-IPFS ships with all multibases [exported by js-multiformats](https://github.com/multiformats/js-multiformats/tree/master/src/bases), including `base58btc`, `base32` and others.
+
+Additional bases can be configured using the `bases` config property.
+
+## Adding additional BlockCodecs, Multihashes and Multibases
+
+If your application requires support for extra codecs, you can configure them as follows:
+
+1. Configure the [IPLD layer](https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs/docs/MODULE.md#optionsipld) of your IPFS daemon to support the codec. This step is necessary so the node knows how to prepare data received over HTTP to be passed to IPLD for serialization:
+
+ ```javascript
+ import { create } from 'ipfs'
+ import customBlockCodec from 'custom-blockcodec'
+ import customMultibase from 'custom-multibase'
+ import customMultihasher from 'custom-multihasher'
+
+ const node = await create({
+ ipld: {
+ // either specify BlockCodecs as part of the `codecs` list
+ codecs: [
+ customBlockCodec
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadCodec: async (codecNameOrCode) => {
+ return import(codecNameOrCode)
+ },
+
+ // either specify Multibase codecs as part of the `bases` list
+ bases: [
+ customMultibase
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadBase: async (baseNameOrCode) => {
+ return import(baseNameOrCode)
+ },
+
+ // either specify Multihash hashers as part of the `hashers` list
+ hashers: [
+ customMultihasher
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadHasher: async (hashNameOrCode) => {
+ return import(hashNameOrCode)
+ }
+ }
+ })
+ ```
+
+2. Configure your IPFS HTTP API Client to support the codec. This is necessary so that the client can send the data to the IPFS node over HTTP:
+
+ ```javascript
+ import { create } from 'ipfs-http-client'
+ import customBlockCodec from 'custom-blockcodec'
+ import customMultibase from 'custom-multibase'
+ import customMultihasher from 'custom-multihasher'
+
+ const client = create({
+ url: 'http://127.0.0.1:5002',
+ ipld: {
+ // either specify BlockCodecs as part of the `codecs` list
+ codecs: [
+ customBlockCodec
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadCodec: async (codecNameOrCode) => {
+ return import(codecNameOrCode)
+ },
+
+ // either specify Multibase codecs as part of the `bases` list
+ bases: [
+ customMultibase
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadBase: async (baseNameOrCode) => {
+ return import(baseNameOrCode)
+ },
+
+ // either specify Multihash hashers as part of the `hashers` list
+ hashers: [
+ customMultihasher
+ ],
+
+ // and/or supply a function to load them dynamically
+ loadHasher: async (hashNameOrCode) => {
+ return import(hashNameOrCode)
+ }
+ }
+ })
+ ```
+
+## Next steps
+
+* See [examples/custom-ipld-formats](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/custom-ipld-formats) for runnable code that demonstrates the above with in-process IPFS nodes, IPFS run as a daemon and also the http client
+* Also [examples/traverse-ipld-graphs](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/traverse-ipld-graphs) which uses the [ipld-format-to-blockcodec](https://www.npmjs.com/package/ipld-format-to-blockcodec) module to use older [IPLD format][]s that have not been ported over to the new [BlockCodec][] interface, as well as additional [Multihash Hashers](https://www.npmjs.com/package/multiformats#multihash-hashers).
+
+[cid]: https://docs.ipfs.io/concepts/content-addressing/
+[blockcodec]: https://www.npmjs.com/package/multiformats#multicodec-encoders--decoders--codecs
+[unixfs]: https://github.com/ipfs/specs/blob/master/UNIXFS.md
+[ipld format]: https://github.com/ipld/interface-ipld-format
+[multihash]: https://github.com/multiformats/multihash
+[multibase]: https://github.com/multiformats/multibase
\ No newline at end of file
diff --git a/docs/MIGRATION-TO-ASYNC-AWAIT.md b/docs/MIGRATION-TO-ASYNC-AWAIT.md
new file mode 100644
index 0000000000..718071a0d4
--- /dev/null
+++ b/docs/MIGRATION-TO-ASYNC-AWAIT.md
@@ -0,0 +1,914 @@
+# Migrating to the new JS IPFS Core API in 0.48.0
+
+A migration guide for refactoring your application code to use the new JS IPFS core API.
+
+Impact key:
+
+* 🍏 easy - simple refactoring in application code
+* 🍋 medium - involved refactoring in application code
+* 🍊 hard - complicated refactoring in application code
+
+## Table of Contents
+
+- [Migrating from callbacks](#migrating-from-callbacks)
+- [Migrating from `PeerId`](#migrating-from-peerid)
+- [Migrating from `PeerInfo`](#migrating-from-peerinfo)
+- [Migrating to Async Iterables](#migrating-to-async-iterables)
+ - [From Node.js Streams](#from-nodejs-streams)
+ - [Node.js Readable Streams](#nodejs-readable-streams)
+ - [Piping Node.js Streams](#piping-nodejs-streams)
+ - [Node.js Transform Streams](#nodejs-transform-streams)
+ - [From Pull Streams](#from-pull-streams)
+ - [Source Pull Streams](#source-pull-streams)
+ - [Pull Stream Pipelines](#pull-stream-pipelines)
+ - [Transform Pull Streams](#transform-pull-streams)
+ - [From buffering APIs](#from-buffering-apis)
+- [Migrating from `addFromFs`](#migrating-from-addfromfs)
+- [Migrating from `addFromURL`](#migrating-from-addfromurl)
+- [Migrating from `addFromStream`](#migrating-from-addfromstream)
+
+## Migrating from callbacks
+
+Callbacks are no longer supported in the API. If your application primarily uses callbacks you have two main options for migration:
+
+**Impact 🍊**
+
+Switch to using the promise API with async/await. Instead of program continuation in a callback, continuation occurs after the async call and functions from where the call is made are changed to be async functions.
+
+e.g.
+
+```js
+function main () {
+ ipfs.id((err, res) => {
+ console.log(res)
+ })
+}
+main()
+```
+
+Becomes:
+
+```js
+async function main () {
+ const res = await ipfs.id()
+ console.log(res)
+}
+main()
+```
+
+**Impact 🍏**
+
+Alternatively you could "callbackify" the API. In this case you use a module to convert the promise API to a callback API either permanently or in an interim period.
+
+e.g.
+
+```js
+function main () {
+ ipfs.id((err, res) => {
+ console.log(res)
+ })
+}
+main()
+```
+
+Becomes:
+
+```js
+const callbackify = require('callbackify')
+const ipfsId = callbackify(ipfs.id)
+
+async function main () {
+ ipfsId((err, res) => {
+ console.log(res)
+ })
+}
+main()
+```
+
+## Migrating from `PeerId`
+
+Libp2p `PeerId` instances are no longer returned from the API. If your application is using the crypto capabilities of [`PeerId`](https://github.com/libp2p/js-peer-id) instances then you'll want to convert the peer ID `string` returned by the new API back into libp2p `PeerId` instances.
+
+**Impact 🍏**
+
+Peer ID strings are also CIDs so converting them is simple:
+
+```js
+const peerId = PeerId.createFromB58String(peerIdStr)
+```
+
+You can get hold of the `PeerId` class using npm or in a script tag:
+
+```js
+import { PeerId } from '@libp2p/interface-peer-id'
+const peerId = PeerId.createFromB58String(peerIdStr)
+```
+
+```html
+
+
+```
+
+## Migrating from `PeerInfo`
+
+Libp2p `PeerInfo` instances are no longer returned from the API. Instead, plain objects of the form `{ id: string, addrs: Multiaddr[] }` are returned. To convert these back into a `PeerInfo` instance:
+
+**Impact 🍏**
+
+Instantiate a new `PeerInfo` and add addresses to it:
+
+```js
+const peerInfo = new PeerInfo(PeerId.createFromB58String(info.id))
+info.addrs.forEach(addr => peerInfo.multiaddrs.add(addr))
+```
+
+You can get hold of the `PeerInfo` class using npm or in a script tag:
+
+```js
+const PeerInfo = require('peer-info')
+import { PeerId } from '@libp2p/interface-peer-id'
+const peerInfo = new PeerInfo(PeerId.createFromB58String(info.id))
+info.addrs.forEach(addr => peerInfo.multiaddrs.add(addr))
+```
+
+```html
+
+
+
+```
+
+## Migrating to Async Iterables
+
+Async Iterables are a language native way of streaming data. The IPFS core API has previously supported two different stream implementations - Pull Streams and Node.js Streams. Similarly to those two different implementations, streaming iterables come in different forms for different purposes:
+
+1. **source** - something that can be consumed. Analogous to a "source" pull stream or a "readable" Node.js stream
+2. **sink** - something that consumes (or drains) a source. Analogous to a "sink" pull stream or a "writable" Node.js stream
+3. **transform** - both a sink and a source where the values it consumes and the values that can be consumed from it are connected in some way. Analogous to a transform in both Pull and Node.js streams
+4. **duplex** - similar to a transform but the values it consumes are not necessarily connected to the values that can be consumed from it
+
+More information and examples here: https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9
+
+List of useful modules for working with async iterables: https://github.com/alanshaw/it-awesome
+
+Note that iterables might gain many helper functions soon: https://github.com/tc39/proposal-iterator-helpers
+
+### From Node.js Streams
+
+#### Node.js Readable Streams
+
+Modern Node.js readable streams are async iterable so there's no changes to any APIs that you'd normally pass a stream to. The `*ReadableStream` APIs have been removed. To migrate from `*ReadableStream` methods, there are a couple of options:
+
+**Impact 🍊**
+
+Use a [for/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop to consume an async iterable.
+
+e.g.
+
+```js
+const readable = ipfs.catReadableStream('QmHash')
+const decoder = new TextDecoder()
+
+readable.on('data', chunk => {
+ console.log(decoder.decode(chunk))
+})
+
+readable.on('end', () => {
+ console.log('done')
+})
+```
+
+Becomes:
+
+```js
+const source = ipfs.cat('QmHash')
+const decoder = new TextDecoder()
+
+for await (const chunk of source) {
+ console.log(decoder.decode(chunk))
+}
+
+console.log('done')
+```
+
+**Impact 🍏**
+
+Convert the async iterable to a readable stream.
+
+e.g.
+
+```js
+const readable = ipfs.catReadableStream('QmHash')
+const decoder = new TextDecoder()
+
+readable.on('data', chunk => {
+ console.log(decoder.decode(chunk))
+})
+
+readable.on('end', () => {
+ console.log('done')
+})
+```
+
+Becomes:
+
+```js
+import toStream from 'it-to-stream'
+const readable = toStream.readable(ipfs.cat('QmHash'))
+const decoder = new TextDecoder()
+
+readable.on('data', chunk => {
+ console.log(decoder.decode(chunk))
+})
+
+readable.on('end', () => {
+ console.log('done')
+})
+```
+
+#### Piping Node.js Streams
+
+Sometimes applications will "pipe" Node.js streams together, using the `.pipe` method or the `pipeline` utility. There are 2 possible migration options:
+
+**Impact 🍊**
+
+Use `it-pipe` and a [for/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop to concat data from an async iterable.
+
+e.g.
+
+```js
+const { pipeline, Writable } = require('stream')
+const decoder = new TextDecoder()
+
+let data = new Uint8Array(0)
+const concat = new Writable({
+ write (chunk, enc, cb) {
+ data = uint8ArrayConcat([data, chunk])
+ cb()
+ }
+})
+
+pipeline(
+ ipfs.catReadableStream('QmHash'),
+ concat,
+ err => {
+ console.log(decoder.decode(chunk))
+ }
+)
+```
+
+Becomes:
+
+```js
+const pipe = require('it-pipe')
+const decoder = new TextDecoder()
+
+let data = new Uint8Array(0)
+const concat = async source => {
+ for await (const chunk of source) {
+ data = uint8ArrayConcat([data, chunk])
+ }
+}
+
+const data = await pipe(
+ ipfs.cat('QmHash'),
+ concat
+)
+
+console.log(decoder.decode(data))
+```
+
+...which, by the way, could more succinctly be written as:
+
+```js
+import toBuffer from 'it-to-buffer'
+const decoder = new TextDecoder()
+const data = await toBuffer(ipfs.cat('QmHash'))
+console.log(decoder.decode(data))
+```
+
+**Impact 🍏**
+
+Convert the async iterable to a readable stream.
+
+e.g.
+
+```js
+const { pipeline, Writable } = require('stream')
+const decoder = new TextDecoder()
+
+let data = new Uint8Array(0)
+const concat = new Writable({
+ write (chunk, enc, cb) {
+ data = uint8ArrayConcat([data, chunk])
+ cb()
+ }
+})
+
+pipeline(
+ ipfs.catReadableStream('QmHash'),
+ concat,
+ err => {
+ console.log(decoder.decode(data))
+ }
+)
+```
+
+Becomes:
+
+```js
+import toStream from 'it-to-stream'
+const { pipeline, Writable } = require('stream')
+const decoder = new TextDecoder()
+
+let data = new Uint8Array(0)
+const concat = new Writable({
+ write (chunk, enc, cb) {
+ data = uint8ArrayConcat([data, chunk])
+ cb()
+ }
+})
+
+pipeline(
+ toStream.readable(ipfs.cat('QmHash')),
+ concat,
+ err => {
+ console.log(decoder.decode(data))
+ }
+)
+```
+
+#### Node.js Transform Streams
+
+Commonly in Node.js you have a readable stream of a file from the filesystem that you want to add to IPFS. There are 2 possible migration options:
+
+**Impact 🍊**
+
+Use `it-pipe` and a [for/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop to collect all items from an async iterable.
+
+e.g.
+
+```js
+import fs from 'fs'
+const { pipeline } = require('stream')
+
+const items = []
+const all = new Writable({
+ objectMode: true,
+ write (chunk, enc, cb) {
+ items.push(chunk)
+ cb()
+ }
+})
+
+pipeline(
+ fs.createReadStream('/path/to/file'),
+ ipfs.addReadableStream(),
+ all,
+ err => {
+ console.log(items)
+ }
+)
+```
+
+Becomes:
+
+```js
+import fs from 'fs'
+const pipe = require('it-pipe')
+
+const items = []
+const all = async source => {
+ for await (const chunk of source) {
+ items.push(chunk)
+ }
+}
+
+await pipe(
+ fs.createReadStream('/path/to/file'), // Because Node.js streams are iterable
+ ipfs.add,
+ all
+)
+
+console.log(items)
+```
+
+...which, by the way, could more succinctly be written as:
+
+```js
+import fs from 'fs'
+const pipe = require('it-pipe')
+import all from 'it-all'
+
+const items = await pipe(
+ fs.createReadStream('/path/to/file'),
+ ipfs.add,
+ all
+)
+
+console.log(items)
+```
+
+**Impact 🍏**
+
+Convert the async iterable to a readable stream.
+
+e.g.
+
+```js
+import fs from 'fs'
+const { pipeline } = require('stream')
+
+const items = []
+const all = new Writable({
+ objectMode: true,
+ write (chunk, enc, cb) {
+ items.push(chunk)
+ cb()
+ }
+})
+
+pipeline(
+ fs.createReadStream('/path/to/file'),
+ ipfs.addReadableStream(),
+ all,
+ err => {
+ console.log(items)
+ }
+)
+```
+
+Becomes:
+
+```js
+import toStream from 'it-to-stream'
+import fs from 'fs'
+const { pipeline } = require('stream')
+
+const items = []
+const all = new Writable({
+ objectMode: true,
+ write (chunk, enc, cb) {
+ items.push(chunk)
+ cb()
+ }
+})
+
+pipeline(
+ fs.createReadStream('/path/to/file'),
+ toStream.transform(ipfs.add),
+ all,
+ err => {
+ console.log(items)
+ }
+)
+```
+
+### From Pull Streams
+
+#### Source Pull Streams
+
+Pull Streams can no longer be passed to IPFS API methods and the `*PullStream` APIs have been removed. To pass a pull stream directly to an IPFS API method, first convert it to an async iterable using [`pull-stream-to-async-iterator`](https://www.npmjs.com/package/pull-stream-to-async-iterator). To migrate from `*PullStream` methods, there are a couple of options:
+
+**Impact 🍊**
+
+Use a [for/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) loop to consume an async iterable.
+
+e.g.
+
+```js
+const decoder = new TextDecoder()
+
+pull(
+ ipfs.catPullStream('QmHash'),
+ pull.through(chunk => {
+ console.log(decoder.decode(data))
+ }),
+ pull.onEnd(err => {
+ console.log('done')
+ })
+)
+```
+
+Becomes:
+
+```js
+const decoder = new TextDecoder()
+
+for await (const chunk of ipfs.cat('QmHash')) {
+ console.log(decoder.decode(data))
+}
+
+console.log('done')
+```
+
+**Impact 🍏**
+
+Convert the async iterable to a pull stream.
+
+e.g.
+
+```js
+const decoder = new TextDecoder()
+
+pull(
+ ipfs.catPullStream('QmHash'),
+ pull.through(chunk => {
+ console.log(decoder.decode(data))
+ }),
+ pull.onEnd(err => {
+ console.log('done')
+ })
+)
+```
+
+Becomes:
+
+```js
+const toPull = require('async-iterator-to-pull-stream')
+const decoder = new TextDecoder()
+
+pull(
+ toPull.source(ipfs.cat('QmHash')),
+ pull.through(chunk => {
+ console.log(decoder.decode(data))
+ }),
+ pull.onEnd(err => {
+ console.log('done')
+ })
+)
+```
+
+#### Pull Stream Pipelines
+
+Frequently, applications will use `pull()` to create a pipeline of pull streams.
+
+**Impact 🍊**
+
+Use `it-pipe` and `it-concat` concat data from an async iterable.
+
+e.g.
+
+```js
+const decoder = new TextDecoder()
+
+pull(
+ ipfs.catPullStream('QmHash'),
+ pull.collect((err, chunks) => {
+ console.log(decoder.decode(uint8ArrayConcat(chunks)))
+ })
+)
+```
+
+Becomes:
+
+```js
+const pipe = require('it-pipe')
+import concat from 'it-concat'
+const decoder = new TextDecoder()
+
+const data = await pipe(
+ ipfs.cat('QmHash'),
+ concat
+)
+
+console.log(decoder.decode(data))
+```
+
+#### Transform Pull Streams
+
+You might have a pull stream source of a file from the filesystem that you want to add to IPFS. There are 2 possible migration options:
+
+**Impact 🍊**
+
+Use `it-pipe` and `it-all` to collect all items from an async iterable.
+
+e.g.
+
+```js
+import fs from 'fs'
+const toPull = require('stream-to-pull-stream')
+
+pull(
+ toPull.source(fs.createReadStream('/path/to/file')),
+ ipfs.addPullStream(),
+ pull.collect((err, items) => {
+ console.log(items)
+ })
+)
+```
+
+Becomes:
+
+```js
+import fs from 'fs'
+
+const file = await ipfs.add(fs.createReadStream('/path/to/file'))
+
+console.log(file)
+```
+
+**Impact 🍏**
+
+Convert the async iterable to a pull stream.
+
+e.g.
+
+```js
+import fs from 'fs'
+const toPull = require('stream-to-pull-stream')
+
+pull(
+ toPull.source(fs.createReadStream('/path/to/file')),
+ ipfs.addPullStream(),
+ pull.collect((err, items) => {
+ console.log(items)
+ })
+)
+```
+
+Becomes:
+
+```js
+import fs from 'fs'
+const streamToPull = require('stream-to-pull-stream')
+const itToPull = require('async-iterator-to-pull-stream')
+
+pull(
+ streamToPull.source(fs.createReadStream('/path/to/file')),
+ itToPull.transform(ipfs.add),
+ pull.collect((err, items) => {
+ console.log(items)
+ })
+)
+```
+
+### From buffering APIs
+
+The old APIs like `ipfs.add`, `ipfs.cat`, `ipfs.ls` and others were "buffering APIs" i.e. they collect all the results into memory before returning them. The new JS core interface APIs are streaming by default in order to reduce memory usage, reduce time to first byte and to provide better feedback. The following are examples of switching from the old `ipfs.add`, `ipfs.cat` and `ipfs.ls` to the new APIs:
+
+**Impact 🍏**
+
+Adding files.
+
+e.g.
+
+```js
+const results = await ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+])
+
+// Note that ALL files have already been added to IPFS
+results.forEach(file => {
+ console.log(file.path)
+})
+```
+
+Becomes:
+
+```js
+const addSource = ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+])
+
+for await (const file of addSource) {
+ console.log(file.path) // Note these are logged out as they are added
+}
+```
+
+Alternatively you can buffer up the results using the `it-all` utility:
+
+```js
+import all from 'it-all'
+
+const results = await all(ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+]))
+
+results.forEach(file => {
+ console.log(file.path)
+})
+```
+
+Often you just want the last item (the root directory entry) when adding multiple files to IPFS:
+
+```js
+const results = await ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+])
+
+const lastResult = results[results.length - 1]
+
+console.log(lastResult)
+```
+
+Becomes:
+
+```js
+const addSource = ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+])
+
+let lastResult
+for await (const file of addSource) {
+ lastResult = file
+}
+
+console.log(lastResult)
+```
+
+Alternatively you can use the `it-last` utility:
+
+```js
+const lastResult = await last(ipfs.addAll([
+ { path: 'root/1.txt', content: 'one' },
+ { path: 'root/2.txt', content: 'two' }
+]))
+
+console.log(lastResult)
+```
+
+**Impact 🍏**
+
+Reading files.
+
+e.g.
+
+```js
+import fs from 'fs'
+
+const data = await ipfs.cat('/ipfs/QmHash')
+
+// Note that here we have read the entire file
+// i.e. `data` holds ALL the contents of the file in memory
+await fs.writeFile('/tmp/file.iso', data)
+
+console.log('done')
+```
+
+Becomes:
+
+```js
+const pipe = require('it-pipe')
+import toIterable from 'stream-to-it'
+import fs from 'fs'
+
+// Note that as chunks arrive they are written to the file and memory can be freed and re-used
+await pipe(
+ ipfs.cat('/ipfs/QmHash'),
+ toIterable.sink(fs.createWriteStream('/tmp/file.iso'))
+)
+
+console.log('done')
+```
+
+Alternatively you can buffer up the chunks using the `it-concat` utility (not recommended!):
+
+```js
+import fs from 'fs'
+import concat from 'it-concat'
+
+const data = await concat(ipfs.cat('/ipfs/QmHash'))
+
+await fs.writeFile('/tmp/file.iso', data.slice())
+
+console.log('done')
+```
+
+**Impact 🍏**
+
+Listing directory contents.
+
+e.g.
+
+```js
+const files = await ipfs.ls('/ipfs/QmHash')
+
+// Note that ALL files in the directory have been read into memory
+files.forEach(file => {
+ console.log(file.name)
+})
+```
+
+Becomes:
+
+```js
+const filesSource = ipfs.ls('/ipfs/QmHash')
+
+for await (const file of filesSource) {
+ console.log(file.name) // Note these are logged out as they are retrieved from the network/disk
+}
+```
+
+Alternatively you can buffer up the directory listing using the `it-all` utility:
+
+```js
+import all from 'it-all'
+
+const results = await all(ipfs.ls('/ipfs/QmHash'))
+
+results.forEach(file => {
+ console.log(file.name)
+})
+```
+
+## Migrating from `addFromFs`
+
+The `addFromFs` API method has been removed and replaced with a helper function `globSource` that is exported from `js-ipfs`/`js-ipfs-http-client`. See the [API docs for `globSource` for more info](https://github.com/ipfs/js-ipfs-http-client/blob/f30031163b9ac4ce2cff34ad4854f24b23cbff0b/README.md#glob-source).
+
+**Impact 🍏**
+
+e.g.
+
+```js
+const IpfsHttpClient = require('ipfs-http-client')
+const ipfs = IpfsHttpClient()
+
+const files = await ipfs.addFromFs('./docs', { recursive: true })
+
+files.forEach(file => {
+ console.log(file)
+})
+```
+
+Becomes:
+
+```js
+const IpfsHttpClient = require('ipfs-http-client')
+const { globSource } = IpfsHttpClient
+const ipfs = IpfsHttpClient()
+
+for await (const file of ipfs.addAll(globSource('./docs', { recursive: true }))) {
+ console.log(file)
+}
+```
+
+## Migrating from `addFromURL`
+
+The `addFromURL` API method has been removed and replaced with a helper function `urlSource` that is exported from `js-ipfs`/`js-ipfs-http-client`. See the [API docs for `urlSource` for more info](https://github.com/ipfs/js-ipfs-http-client/blob/f30031163b9ac4ce2cff34ad4854f24b23cbff0b/README.md#url-source).
+
+**Impact 🍏**
+
+e.g.
+
+```js
+const IpfsHttpClient = require('ipfs-http-client')
+const ipfs = IpfsHttpClient()
+
+const files = await ipfs.addFromURL('https://ipfs.io/images/ipfs-logo.svg')
+
+files.forEach(file => {
+ console.log(file)
+})
+```
+
+Becomes:
+
+```js
+const IpfsHttpClient = require('ipfs-http-client')
+const { urlSource } = IpfsHttpClient
+const ipfs = IpfsHttpClient()
+
+const file = await ipfs.add(urlSource('https://ipfs.io/images/ipfs-logo.svg'))
+
+console.log(file)
+```
+
+## Migrating from `addFromStream`
+
+The `addFromStream` API method has been removed. This was an alias for `add`.
+
+**Impact 🍏**
+
+e.g.
+
+```js
+const IpfsHttpClient = require('ipfs-http-client')
+const ipfs = IpfsHttpClient()
+
+const files = await ipfs.addFromStream(fs.createReadStream('/path/to/file.txt'))
+
+files.forEach(file => {
+ console.log(file)
+})
+```
+
+Becomes:
+
+```js
+import fs from 'fs'
+const ipfs = IpfsHttpClient()
+
+const file = await ipfs.add(fs.createReadStream('/path/to/file.txt'))
+
+console.log(file)
+```
diff --git a/docs/MODULE.md b/docs/MODULE.md
new file mode 100644
index 0000000000..23e612d708
--- /dev/null
+++ b/docs/MODULE.md
@@ -0,0 +1,480 @@
+# IPFS Module
+
+Use the IPFS module as a dependency of your project to spawn in process instances of IPFS in node.js, the browser, electron, etc.
+
+## Table of contents
+
+- [Getting started](#getting-started)
+- [IPFS.create([options])](#ipfscreateoptions)
+ - [`options.repo`](#optionsrepo)
+ - [`options.repoAutoMigrate`](#optionsrepoautomigrate)
+ - [`options.init`](#optionsinit)
+ - [`options.start`](#optionsstart)
+ - [`options.pass`](#optionspass)
+ - [`options.silent`](#optionssilent)
+ - [`options.relay`](#optionsrelay)
+ - [`options.offline`](#optionsoffline)
+ - [`options.preload`](#optionspreload)
+ - [`options.EXPERIMENTAL`](#optionsexperimental)
+ - [`options.config`](#optionsconfig)
+ - [`options.ipld`](#optionsipld)
+ - [`options.libp2p`](#optionslibp2p)
+ - [Instance methods](#instance-methods)
+ - [`node.start()`](#nodestart)
+- [Static types and utils](#static-types-and-utils)
+ - [Glob source](#glob-source)
+ - [`globSource(path, pattern, [options])`](#globsourcepath-pattern-options)
+ - [Example](#example)
+ - [URL source](#url-source)
+ - [`urlSource(url)`](#urlsourceurl)
+ - [Example](#example-1)
+ - [Path](#path)
+ - [`path()`](#path-1)
+ - [Example](#example-2)
+
+## Getting started
+
+Create a running node with:
+
+```javascript
+// Create the IPFS node instance
+const node = await IPFS.create()
+// Your node is now ready to use \o/
+
+await node.stop()
+// node is now 'offline'
+```
+
+The node returned from `IPFS.create()` supports the [IPFS Core API](https://github.com/ipfs/js-ipfs/tree/master/docs/core-api), along with some additional methods documented below.
+
+## IPFS.create([options])
+
+```js
+const node = await IPFS.create([options])
+```
+
+Creates and returns a ready to use instance of an IPFS node.
+
+Use the `options` argument to specify advanced configuration. It is an object with any of these properties:
+
+### `options.repo`
+
+| Type | Default |
+|------|---------|
+| string or [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance | `'~/.jsipfs'` in Node.js, `'ipfs'` in browsers |
+
+The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo) instance.
+
+Example:
+
+```js
+// Store data outside your user directory
+const node = await IPFS.create({ repo: '/var/ipfs/data' })
+```
+
+### `options.repoAutoMigrate`
+
+| Type | Default |
+| --------- | ------- |
+| `boolean` | `true` |
+
+`js-ipfs` comes bundled with a tool that automatically migrates your IPFS repository when a new version is available.
+
+**For apps that build on top of `js-ipfs` and run in the browser environment, be aware that disabling automatic
+migrations leaves the user with no way to run the migrations because there is no CLI in the browser. In such
+a case, you should provide a way to trigger migrations manually.**
+
+### `options.init`
+
+| Type | Default |
+| ----------------- | ------- |
+| boolean or object | `true` |
+
+Perform repo initialization steps when creating the IPFS node.
+
+Note that *initializing* a repo is different from creating an instance of [`ipfs.Repo`](https://github.com/ipfs/js-ipfs-repo). The IPFS constructor sets many special properties when initializing a repo, so you should usually not try and call `repoInstance.init()` yourself.
+
+Instead of a boolean, you may provide an object with custom initialization options. All properties are optional:
+
+- `emptyRepo` (boolean) Whether to remove built-in assets, like the instructional tour and empty mutable file system, from the repo. (Default: `false`)
+- `algorithm` (string) The type of key to use. Supports `rsa`, `ed25519`, `secp256k1`. (Default: `rsa`)
+- `bits` (number) Number of bits to use in the generated key pair (rsa only). (Default: `2048`)
+- `privateKey` (string/PeerId) A pre-generated private key to use. Can be either a base64 string or a [PeerId](https://github.com/libp2p/js-peer-id) instance. **NOTE: This overrides `bits`.**
+ ```js
+ // Generating a Peer ID:
+ import { PeerId } from '@libp2p/interface-peer-id'
+ // Generates a new Peer ID, complete with public/private keypair
+ // See https://github.com/libp2p/js-peer-id
+ const peerId = await PeerId.create({ bits: 2048 })
+ ```
+- `pass` (string) A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set).
+- `profiles` (Array) Apply profile settings to config.
+- `allowNew` (boolean, default: `true`) Set to `false` to disallow initialization if the repo does not already exist.
+
+### `options.start`
+
+| Type | Default |
+| --------- | ------- |
+| `boolean` | `true` |
+
+If `false`, do not automatically start the IPFS node. Instead, you’ll need to manually call [`node.start()`](#nodestart) yourself.
+
+### `options.pass`
+
+| Type | Default |
+| ------ | ------- |
+| string | `null` |
+
+A passphrase to encrypt/decrypt your keys.
+
+### `options.silent`
+
+| Type | Default |
+| ------- | ------- |
+| Boolean | `false` |
+
+Prevents all logging output from the IPFS node.
+
+### `options.relay`
+
+| Type | Default |
+|------|---------|
+| object | `{ enabled: true, hop: { enabled: false, active: false } }` |
+
+Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/circuit-relaying) to learn more).
+
+- `enabled` (boolean): Enable circuit relay dialer and listener. (Default: `true`)
+- `hop` (object)
+ - `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`)
+ - `active` (boolean): Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`)
+
+### `options.offline`
+
+| Type | Default |
+| ------- | ------- |
+| Boolean | `false` |
+
+Run ipfs node offline. The node does not connect to the rest of the network but provides a local API.
+
+### `options.preload`
+
+| Type | Default |
+| ------ | ------------------------------------- |
+| object | `{ enabled: true, addresses: [...] }` |
+
+Configure remote preload nodes. The remote will preload content added on this node, and also attempt to preload objects requested by this node.
+
+- `enabled` (boolean): Enable content preloading (Default: `true`)
+- `addresses` (array): Multiaddr API addresses of nodes that should preload content. **NOTE:** nodes specified here should also be added to your node's bootstrap address list at [`config.Bootstrap`](#optionsconfig).
+
+### `options.EXPERIMENTAL`
+
+| Type | Default |
+| ------ | ---------------------------------------- |
+| object | `{ ipnsPubsub: false, sharding: false }` |
+
+Enable and configure experimental features.
+
+- `ipnsPubsub` (boolean): Enable pub-sub on IPNS. (Default: `false`)
+- `sharding` (boolean): Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`)
+
+### `options.config`
+
+| Type | Default |
+|------|---------|
+| object | [`config.js`](https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs-core-config/src/config.js) in Node.js, [`config-browser.js`](https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs-core-config/src/config.browser.js) in browsers |
+
+Modify the default IPFS node config. This object will be *merged* with the default config; it will not replace it. The default config is documented in [the js-ipfs config file docs](./CONFIG.md).
+
+### `options.ipld`
+
+| Type | Default |
+|------|---------|
+| object | [`ipld.js`](https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs-core-config/src/ipld.js) |
+
+Modify the default IPLD config. This object will be *merged* with the default config; it will not replace it. Check IPLD [docs](https://github.com/ipld/js-ipld#ipld-constructor) for more information on the available options.
+
+> Browser config does **NOT** include by default all the IPLD formats. Only `ipld-dag-pb`, `ipld-dag-cbor` and `ipld-raw` are included.
+
+To add support for other formats we provide two options, one sync and another async.
+
+Examples for the sync option:
+
+ESM Environments
+
+```js
+import ipldGit from 'ipld-git'
+import ipldBitcoin from 'ipld-bitcoin'
+import { convert } from 'ipld-format-to-blockcodec'
+
+const node = await IPFS.create({
+ ipld: {
+ codecs: [
+ convert(ipldGit),
+ convert(ipldBitcoin)
+ ]
+ }
+})
+```
+
+
+Commonjs Environments
+
+```js
+const IPFS = require('ipfs')
+const ipldGit = require('ipld-git')
+const ipldBitcoin = require('ipld-bitcoin')
+const { convert } = require('ipld-format-to-blockcodec')
+
+const node = await IPFS.create({
+ ipld: {
+ codecs: [
+ convert(ipldGit),
+ convert(ipldBitcoin)
+ ]
+ }
+})
+```
+
+
+Using script tags
+
+```html
+
+
+
+
+
+```
+
+
+
+Examples for the async option:
+
+ESM Environments
+
+```js
+const node = await IPFS.create({
+ ipld: {
+ async loadCodec (codec) {
+ if (codec === multicodec.GIT_RAW) {
+ return convert(await import('ipld-git')) // This is a dynamic import
+ } else {
+ throw new Error('unable to load format ' + multicodec.print[codec])
+ }
+ }
+ }
+})
+```
+
+> For more information about dynamic imports please check [webpack docs](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or search your bundler documention.
+
+Using dynamic imports will tell your bundler to create a separate file (normally called *chunk*) that will **only** be requested by the browser if it's really needed. This strategy will reduce your bundle size and load times without removing any functionality.
+
+With Webpack IPLD formats can even be grouped together using magic comments `import(/* webpackChunkName: "ipld-formats" */ 'ipld-git')` to produce a single file with all of them.
+
+
+
+Commonjs Environments
+
+```js
+const node = await IPFS.create({
+ ipld: {
+ async loadFormat (codec) {
+ if (codec === multicodec.GIT_RAW) {
+ return require('ipld-git')
+ } else {
+ throw new Error('unable to load format ' + multicodec.print[codec])
+ }
+ }
+ }
+})
+```
+
+
+
+Using Script tags
+
+```js
+
+
+```
+
+
+
+### `options.libp2p`
+
+| Type | Default |
+|------|---------|
+| object | [`libp2p-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-core-config/src/libp2p-nodejs.js) in Node.js, [`libp2p-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-core-config/src)/libp2p-browser.js) in browsers |
+| function | [`libp2p bundle`](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/custom-libp2p) |
+
+The libp2p option allows you to build your libp2p node by configuration, or via a bundle function. If you are looking to just modify the below options, using the object format is the quickest way to get the default features of libp2p. If you need to create a more customized libp2p node, such as with custom transports or peer/content routers that need some of the ipfs data on startup, a custom bundle is a great way to achieve this.
+
+You can see the bundle in action in the [custom libp2p example](https://github.com/ipfs-examples/js-ipfs-examples/tree/master/examples/custom-libp2p).
+
+Please see [libp2p/docs/CONFIGURATION.md](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md) for the list of options libp2p supports.
+
+### Instance methods
+
+#### `node.start()`
+
+Start listening for connections with other IPFS nodes on the network. In most cases, you do not need to call this method — `IPFS.create()` will automatically do it for you.
+
+This method is asynchronous and returns a promise.
+
+```js
+const node = await IPFS.create({ start: false })
+console.log('Node is ready to use but not started!')
+
+try {
+ await node.start()
+ console.log('Node started!')
+} catch (/** @type {any} */ error) {
+ console.error('Node failed to start!', error)
+}
+```
+
+## Static types and utils
+
+Aside from the default export, `ipfs` exports various types and utilities that are included in the bundle:
+
+- [`crypto`](https://www.npmjs.com/package/libp2p-crypto)
+- [`isIPFS`](https://www.npmjs.com/package/is-ipfs)
+- [`Buffer`](https://www.npmjs.com/package/buffer)
+- [`PeerId`](https://docs.libp2p.io/concepts/peer-id/)
+- [`PeerInfo`](https://www.npmjs.com/package/peer-info)
+- [`multiaddr`](https://www.npmjs.com/package/multiaddr)
+- [`multibase`](https://www.npmjs.com/package/multibase)
+- [`multihash`](https://www.npmjs.com/package/multihashes)
+- [`multihashing`](https://www.npmjs.com/package/multihashing-async)
+- [`multicodec`](https://www.npmjs.com/package/multicodec)
+- [`CID`](https://docs.ipfs.io/concepts/content-addressing)
+
+These can be accessed like this, for example:
+
+```js
+const { CID } = require('ipfs')
+// ...or from an es-module:
+import { CID } from 'ipfs'
+```
+
+##### Glob source
+
+A utility to allow files on the file system to be easily added to IPFS.
+
+###### `globSource(path, pattern, [options])`
+
+- `path`: A path to a single file or directory to glob from
+- `pattern`: A pattern to match files under `path`
+- `options`: Optional options
+- `options.hidden`: Hidden/dot files (files or folders starting with a `.`, for example, `.git/`) are not included by default. To add them, use the option `{ hidden: true }`.
+
+Returns an async iterable that yields `{ path, content }` objects suitable for passing to `ipfs.add`.
+
+###### Example
+
+```js
+import { create, globSource } from 'ipfs'
+
+const ipfs = await create()
+
+for await (const file of ipfs.addAll(globSource('./docs', '**/*'))) {
+ console.log(file)
+}
+/*
+{
+ path: 'docs/assets/anchor.js',
+ cid: CID('QmVHxRocoWgUChLEvfEyDuuD6qJ4PhdDL2dTLcpUy3dSC2'),
+ size: 15347
+}
+{
+ path: 'docs/assets/bass-addons.css',
+ cid: CID('QmPiLWKd6yseMWDTgHegb8T7wVS7zWGYgyvfj7dGNt2viQ'),
+ size: 232
+}
+...
+*/
+```
+
+##### URL source
+
+A utility to allow content from the internet to be easily added to IPFS.
+
+###### `urlSource(url)`
+
+- `url`: A string URL or [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) instance to send HTTP GET request to
+
+Returns an async iterable that yields `{ path, content }` objects suitable for passing to `ipfs.add`.
+
+###### Example
+
+```js
+import { create, urlSource } from 'ipfs'
+
+const ipfs = await create()
+
+const file = await ipfs.add(urlSource('https://ipfs.io/images/ipfs-logo.svg'))
+console.log(file)
+
+/*
+{
+ path: 'ipfs-logo.svg',
+ cid: CID('QmTqZhR6f7jzdhLgPArDPnsbZpvvgxzCZycXK7ywkLxSyU'),
+ size: 3243
+}
+*/
+```
+
+##### Path
+
+A function that returns the path to the js-ipfs CLI.
+
+This is analogous to the `.path()` function exported by the [go-ipfs](https://www.npmjs.com/package/go-ipfs) module.
+
+###### `path()`
+
+Returns the path to the js-ipfs CLI
+
+###### Example
+
+```js
+import { path } from 'ipfs'
+
+console.info(path()) // /foo/bar/node_modules/ipfs/src/cli.js
+```
diff --git a/docs/MONITORING.md b/docs/MONITORING.md
new file mode 100644
index 0000000000..1b0cc29cfa
--- /dev/null
+++ b/docs/MONITORING.md
@@ -0,0 +1,15 @@
+# Monitoring
+
+The HTTP API exposed with js-ipfs can also be used for exposing metrics about the running js-ipfs node and other Node.js metrics.
+
+To enable it, you need to set the environment variable `IPFS_MONITORING` (any value). E.g.
+
+```console
+$ IPFS_MONITORING=true jsipfs daemon
+```
+
+Once the environment variable is set and the js-ipfs daemon is running, you can get the metrics (in prometheus format) by making a GET request to the following endpoint:
+
+```
+http://localhost:5002/debug/metrics/prometheus
+```
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000000..374833fd4c
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,37 @@
+# IPFS Docs
+
+- [API Docs](#api-docs)
+- [How tos and other documentation](#how-tos-and-other-documentation)
+- [Development documentation](#development-documentation)
+
+## API Docs
+
+`ipfs` can run as part of your program (an in-process node) or as a standalone daemon process that can be communicated with via an HTTP RPC API using the [`ipfs-http-client`](../packages/ipfs-http-client) module.
+
+Whether accessed directly or over HTTP, both methods support the full [Core API](#core-api). In addition other methods are available to construct instances of each module, etc.
+
+* [Core API docs](./core-api/README.md)
+* [IPFS API](../packages/ipfs/README.md)
+* [IPFS-HTTP-CLIENT API](../packages/ipfs-http-client/README.md)
+
+## How tos and other documentation
+
+* [Architecture overview](./ARCHITECTURE.md)
+* [How to run js-IPFS in the browser](./BROWSERS.md)
+* [Running js-IPFS on the CLI](./CLI.md)
+* [js-IPFS configuration options](./CONFIG.md)
+* [How to configure CORS for use with the http client](./CORS.md)
+* [Running js-IPFS as a daemon](./DAEMON.md)
+* [Configuring Delegate Routers](./DELEGATE_ROUTERS.md)
+* [Running js-IPFS under Docker](./DOCKER.md)
+* [FAQ](./FAQ.md)
+* [How to configure additional IPLD codecs](./IPLD.md)
+* [Running js-IPFS in your application](./MODULE.md)
+* [How to get metrics out of js-IPFS](./MONITORING.md)
+
+## Development documentation
+
+* [Getting started](./DEVELOPMENT.md)
+* [Release issue template](./RELEASE_ISSUE_TEMPLATE.md)
+* [Early testers](./EARLY_TESTERS.md)
+* [Releases](./RELEASES.md)
diff --git a/docs/RELEASES.md b/docs/RELEASES.md
new file mode 100644
index 0000000000..969c200223
--- /dev/null
+++ b/docs/RELEASES.md
@@ -0,0 +1,112 @@
+# Releases
+
+## Table of Contents
+
+- [Release Philosophy](#release-philosophy)
+- [Release Flow](#release-flow)
+ - [Stage 0 - Automated Testing](#stage-0---automated-testing)
+ - [Stage 1 - Internal Testing](#stage-1---internal-testing)
+ - [Stage 2 - Community Dev Testing](#stage-2---community-dev-testing)
+ - [Stage 3 - Community Prod Testing](#stage-3---community-prod-testing)
+ - [Stage 4 - Release](#stage-4---release)
+- [Release Cycle](#release-cycle)
+ - [Patch Releases](#patch-releases)
+- [Performing a Release](#performing-a-release)
+- [Release Version Numbers](#release-version-numbers)
+ - [Release Candidates](#release-candidates)
+
+## Release Philosophy
+
+js-ipfs aims to have release every six weeks, two releases per quarter. During these 6 week releases, we go through 4 different stages that gives us the opportunity to test the new version against our test environments (unit, interop, integration), QA in our current production environment, IPFS apps (e.g. Desktop and WebUI) and with our community and _early testers_[1] that have IPFS running in production.
+
+We might expand the six week release schedule in case of:
+
+- No new updates to be added
+- In case of a large community event that takes the core team availability away (e.g. IPFS Conf, Dev Meetings, IPFS Camp, etc.)
+
+## Release Flow
+
+js-ipfs releases come in 5 stages designed to gradually roll out changes and reduce the impact of any regressions that may have been introduced. If we need to merge non-trivial[2] changes during the process, we start over at stage 0.
+
+
+
+### Stage 0 - Automated Testing
+
+At this stage, we expect _all_ automated tests (unit, functional, integration, interop, testlab, performance, etc.) to pass.
+
+### Stage 1 - Internal Testing
+
+At this stage, we'll:
+
+1. Start a partial-rollout to our own infrastructure.
+2. Test against applications in the [ipfs](https://github.com/ipfs/) and [ipfs-shipyard](https://github.com/ipfs-shipyard/) organisations and a selection of other hand picked projects.
+
+**Goals:**
+
+1. Make sure we haven't introduced any obvious regressions.
+2. Test the release in an environment we can monitor and easily roll back (i.e. our own infra).
+
+### Stage 2 - Community Dev Testing
+
+At this stage, we'll announce the impending release to the community and ask for pre-release testers.
+
+**Goal:**
+
+Test the release in as many non-production environments as possible. This is relatively low-risk but gives us a _breadth_ of testing internal testing can't.
+
+### Stage 3 - Community Prod Testing
+
+At this stage, we consider the release to be "production ready" and will ask the community and our early testers to (partially) deploy the release to their production infrastructure.
+
+**Goals:**
+
+1. Test the release in some production environments with heavy workloads.
+2. Partially roll-out an upgrade to see how it affects the network.
+3. Retain the ability to ship last-minute fixes before the final release.
+
+### Stage 4 - Release
+
+At this stage, the release is "battle hardened" and ready for wide deployment. A new version is published to npm, announcements are made and a blog post is published to [blog.ipfs.io](https://blog.ipfs.io).
+
+## Release Cycle
+
+A full release process should take about 3 weeks, a week per stage 1-3. We will start a new process every 6 weeks, regardless of when the previous release landed unless it's still ongoing.
+
+### Patch Releases
+
+If we encounter a serious bug in the stable latest release, we will create a patch release based on this release. For now, bug fixes will _not_ be backported to previous releases.
+
+Patch releases will usually follow a compressed release cycle and should take 2-3 days. In a patch release:
+
+1. Automated and internal testing (stage 0 and 1) will be compressed into a few hours - ideally less than a day.
+2. Stage 2 will be skipped.
+3. Community production testing will be shortened to 1-2 days of opt-in testing in production (early testers can choose to pass).
+
+Some patch releases, especially ones fixing one or more complex bugs, may undergo the full release process.
+
+## Performing a Release
+
+The release is managed by the "Lead Maintainer" for js-ipfs. It starts with the opening of an issue containing the content available on the [RELEASE_ISSUE_TEMPLATE](./RELEASE_ISSUE_TEMPLATE.md) not more than **48 hours** after the previous release.
+
+This issue is pinned and labeled ["release"](https://github.com/ipfs/js-ipfs/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Arelease). When the cycle is due to begin the 5 stages will be followed until the release is done.
+
+## Release Version Numbers
+
+js-ipfs is currently pre-1.0. In semver terms this means [anything may change at any time](https://semver.org/#spec-item-4).
+
+However, pre-1.0 js-ipfs reserves MINOR version increments for BREAKING CHANGES _and_ feature additions and PATCH version increments for bug fixes.
+
+Post `1.x.x` (future), MAJOR version number increments will contain BREAKING CHANGES, MINOR version increments will be reserved for backwards compatible new features and PATCH version increments for bug fixes.
+
+We do not yet retroactively apply fixes to older releases (no Long Term Support releases for now), which means that we always recommend users to update to the latest, whenever possible.
+
+### Release Candidates
+
+Every commit to master results in the publishing of a Release Candidate. These are made available for users who want to try out the "bleeding edge" and can be installed using version numbers with the form `x.y.z-rc.n` where `x`, `y`, and `z` are the usual MAJOR, MINOR and PATCH version numbers and `n` (starting at 0) which is the number of commits to master since the last full release.
+
+Alternatively the latest RC is tagged `next` on npm and can be installed using `npm install ipfs@next`.
+
+---
+
+- **[1]** - _early testers_ is an IPFS programme in which members of the community can self-volunteer to help test `js-ipfs` Release Candidates. You find more info about it at [EARLY_TESTERS.md](./EARLY_TESTERS.md)
+- **[2]** - A non-trivial change is any change that could potentially introduce an issue that could not categorically be caught by automated testing. This is up to the discretion of the Lead Maintainer but the assumption is that every change is non-trivial unless proven otherwise.
diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md
new file mode 100644
index 0000000000..6a9f36c5da
--- /dev/null
+++ b/docs/RELEASE_ISSUE_TEMPLATE.md
@@ -0,0 +1,128 @@
+# Release Template
+
+> short tl;dr; of the release
+
+# 🗺 What's left for release
+
+
+
+# 🚢 Estimated shipping date
+
+
+
+# 🔦 Highlights
+
+
+
+# 🏗 API Changes
+
+
+
+# ✅ Release Checklist
+
+- [ ] **Stage 0 - Automated Testing**
+ - [ ] Feature freeze. If any "non-trivial" changes (see the footnotes of [docs/releases.md](https://github.com/ipfs/js-ipfs/tree/master/docs/releases.md) for a definition) get added to the release, uncheck all the checkboxes and return to this stage.
+ - [ ] Automated Testing (already tested in CI) - Ensure that all tests are passing, this includes:
+ - [ ] unit/functional/integration/e2e
+ - [ ] interop
+ - [ ] ~~sharness~~ (Does not run `js-ipfs`)
+ - [ ] all the examples run without problems
+ - [ ] IPFS application testing
+ - [ ] ~~[webui](https://github.com/ipfs-shipyard/ipfs-webui)~~ (Does not depend on `js-ipfs` or `js-ipfs-http-client`)
+ - [ ] ~~[ipfs-desktop](https://github.com/ipfs-shipyard/ipfs-desktop)~~ (Does not depend on `js-ipfs` or `js-ipfs-http-client`)
+ - [ ] [ipfs-companion](https://github.com/ipfs-shipyard/ipfs-companion)
+ - [ ] [npm-on-ipfs](https://github.com/ipfs-shipyard/npm-on-ipfs)
+ - [ ] [peer-base](https://github.com/peer-base/peer-base)
+ - [ ] [service-worker-gateway](https://github.com/ipfs-shipyard/service-worker-gateway)
+ - [ ] Third party application testing
+ - [ ] [ipfs-log](https://github.com/orbitdb/ipfs-log)
+ - [ ] [orbit-db](https://github.com/orbitdb/orbit-db)
+ - [ ] [sidetree](https://github.com/decentralized-identity/sidetree)
+- [ ] **Stage 1 - Internal Testing**
+ - [ ] Documentation
+ - [ ] Ensure that [README.md](https://github.com/ipfs/js-ipfs/tree/master/README.md) is up to date
+ - [ ] Install section
+ - [ ] API calls
+ - [ ] Packages Listing
+ - [ ] Publish a release candidate to npm
+ ```sh
+ # All successful builds of master update the `build/last-successful` branch
+ # which contains an `npm-shrinkwrap.json`.
+ # This command checks that branch out, installs it's dependencies using `npm ci`,
+ # creates a release branch (e.g. release/v0.34.x), updates the minor prerelease
+ # version (e.g. 0.33.1 -> 0.34.0-rc.0) and publishes it to npm.
+ npx aegir publish-rc
+
+ # Later we may wish to update the rc. First cherry-pick/otherwise merge the
+ # new commits into the release branch on github (e.g. not locally) and wait
+ # for CI to pass. Then update the lockfiles used by CI (n.b. one day this
+ # will be done by our ci tools) with this command:
+ npx aegir update-release-branch-lockfiles release/v0.34.x
+
+ # Then update the rc published on npm. This command pulls the specified
+ # release branch, installs it's dependencies `npm ci`, increments the
+ # prerelease version (e.g. 0.34.0-rc.0 -> 0.34.0-rc.1) and publishes it
+ # to npm.
+ npx aegir update-rc release/v0.34.x
+ ```
+ - Network Testing:
+ - test lab things - TBD
+ - Infrastructure Testing:
+ - TBD
+- [ ] **Stage 2 - Community Dev Testing**
+ - [ ] Reach out to the IPFS _early testers_ listed in [docs/EARLY_TESTERS.md](https://github.com/ipfs/js-ipfs/tree/master/docs/EARLY_TESTERS.md) for testing this release (check when no more problems have been reported). If you'd like to be added to this list, please file a PR.
+ - [ ] Reach out on IRC for additional early testers.
+- [ ] **Stage 3 - Community Prod Testing**
+ - [ ] Update [js.ipfs.io](https://js.ipfs.io) examples to use the latest js-ipfs
+ - [ ] Invite the IPFS [_early testers_](https://github.com/ipfs/js-ipfs/tree/master/docs/EARLY_TESTERS.md) to deploy the release to part of their production infrastructure.
+ - [ ] Invite the wider community (link to the release issue):
+ - [ ] [discuss.ipfs.io](https://discuss.ipfs.io/c/announcements)
+ - [ ] Twitter
+ - [ ] IRC
+- [ ] **Stage 4 - Release**
+ - [ ] Take a snapshot of everyone that has contributed to this release (including its direct dependencies in IPFS, libp2p, IPLD and multiformats) using [the js-ipfs-contributors module](https://www.npmjs.com/package/js-ipfs-contributors).
+ - [ ] Publish to npm:
+ ```sh
+ git checkout release/v0.34.x
+
+ # Re-install dependencies using lockfile (will automatically remove your
+ # node_modules folder) (Ensures the versions used for the browser build are the
+ # same that have been verified by CI)
+ npm ci
+
+ # lint, build, test, tag, publish
+ npm run release-minor
+
+ # reintegrate release branch into master
+ git rm npm-shrinkwrap.json yarn.lock
+ git commit -m 'chore: removed lock files'
+ git checkout master
+ git merge release/v0.34.x
+ git push
+ ```
+ - [ ] Publish a blog post to [github.com/ipfs/blog](https://github.com/ipfs/blog) (at minimum, a c&p of this release issue with all the highlights, API changes and thank yous)
+ - [ ] Broadcasting (link to blog post)
+ - [ ] Twitter
+ - [ ] IRC
+ - [ ] [Reddit](https://reddit.com/r/ipfs)
+ - [ ] [discuss.ipfs.io](https://discuss.ipfs.io/c/announcements)
+ - [ ] Announce it on the [IPFS Users Mailing List](https://groups.google.com/forum/#!forum/ipfs-users)
+ - [ ] Copy release notes to the [GitHub Release description](https://github.com/ipfs/js-ipfs/releases)
+
+# ❤️ Huge thank you to everyone that made this release possible
+
+
+
+# 🙌🏽 Want to contribute?
+
+Would you like to contribute to the IPFS project and don't know how? Well, there are a few places you can get started:
+
+- Check the issues with the `help wanted` label in the [js-ipfs repo](https://github.com/ipfs/js-ipfs/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
+- Join an IPFS All Hands, introduce yourself and let us know where you would like to contribute - https://github.com/ipfs/team-mgmt/#weekly-ipfs-all-hands
+- Hack with IPFS and show us what you made! The All Hands call is also the perfect venue for demos, join in and show us what you built
+- Join the discussion at https://discuss.ipfs.io/ and help users finding their answers.
+- Join the [🚀 IPFS Core Implementations Weekly Sync 🛰](https://github.com/ipfs/team-mgmt/issues/992) and be part of the action!
+
+# ⁉️ Do you have questions?
+
+The best place to ask your questions about IPFS, how it works and what you can do with it is at [discuss.ipfs.io](https://discuss.ipfs.io). We are also available at the `#ipfs` channel on Freenode.
diff --git a/docs/core-api/BITSWAP.md b/docs/core-api/BITSWAP.md
new file mode 100644
index 0000000000..41cc548399
--- /dev/null
+++ b/docs/core-api/BITSWAP.md
@@ -0,0 +1,197 @@
+# Bitswap API
+
+- [`ipfs.bitswap.wantlist([options])`](#ipfsbitswapwantlistoptions)
+ - [Parameters](#parameters)
+ - [Options](#options)
+ - [Returns](#returns)
+ - [Example](#example)
+- [`ipfs.bitswap.wantlistForPeer(peerId, [options])`](#ipfsbitswapwantlistforpeerpeerid-options)
+ - [Parameters](#parameters-1)
+ - [Options](#options-1)
+ - [Returns](#returns-1)
+ - [Example](#example-1)
+- [`ipfs.bitswap.unwant(cids, [options])`](#ipfsbitswapunwantcids-options)
+ - [Parameters](#parameters-2)
+ - [Options](#options-2)
+ - [Returns](#returns-2)
+ - [Example](#example-2)
+- [`ipfs.bitswap.stat([options])`](#ipfsbitswapstatoptions)
+ - [Parameters](#parameters-3)
+ - [Options](#options-3)
+ - [Returns](#returns-3)
+ - [Example](#example-3)
+
+## `ipfs.bitswap.wantlist([options])`
+
+> Returns the wantlist for your node
+
+### Parameters
+
+None
+
+### Options
+
+An optional object which may have the following keys:
+
+| Name | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| timeout | `Number` | `undefined` | A timeout in ms |
+| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
+
+### Returns
+
+| Type | Description |
+| -------- | -------- |
+| `Promise` | An array of [CID][]s currently in the wantlist |
+
+### Example
+
+```JavaScript
+const list = await ipfs.bitswap.wantlist()
+console.log(list)
+// [ CID('QmHash') ]
+```
+
+A great source of [examples][] can be found in the tests for this API.
+
+## `ipfs.bitswap.wantlistForPeer(peerId, [options])`
+
+> Returns the wantlist for a connected peer
+
+### Parameters
+
+| Name | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| peerId | [PeerId][] | A peer ID to return the wantlist for |
+
+### Options
+
+An optional object which may have the following keys:
+
+| Name | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| timeout | `Number` | `undefined` | A timeout in ms |
+| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
+
+### Returns
+
+| Type | Description |
+| -------- | -------- |
+| `Promise` | An array of [CID][]s currently in the wantlist |
+
+### Example
+
+```JavaScript
+const list = await ipfs.bitswap.wantlistForPeer(peerId)
+console.log(list)
+// [ CID('QmHash') ]
+```
+
+A great source of [examples][] can be found in the tests for this API.
+
+## `ipfs.bitswap.unwant(cids, [options])`
+
+> Removes one or more CIDs from the wantlist
+
+### Parameters
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| cids | A [CID][] or Array of [CID][]s | The CIDs to remove from the wantlist |
+
+### Options
+
+An optional object which may have the following keys:
+
+| Name | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| timeout | `Number` | `undefined` | A timeout in ms |
+| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
+
+### Returns
+
+| Type | Description |
+| -------- | -------- |
+| `Promise` | A promise that resolves once the request is complete |
+
+### Example
+
+```JavaScript
+let list = await ipfs.bitswap.wantlist()
+console.log(list)
+// [ CID('QmHash') ]
+
+await ipfs.bitswap.unwant(cid)
+
+list = await ipfs.bitswap.wantlist()
+console.log(list)
+// []
+```
+
+A great source of [examples][] can be found in the tests for this API.
+
+## `ipfs.bitswap.stat([options])`
+
+> Show diagnostic information on the bitswap agent.
+
+Note: `bitswap.stat` and `stats.bitswap` can be used interchangeably.
+
+### Parameters
+
+None
+
+### Options
+
+An optional object which may have the following keys:
+
+| Name | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| timeout | `Number` | `undefined` | A timeout in ms |
+| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
+
+### Returns
+
+| Type | Description |
+| -------- | -------- |
+| `Promise