{"id":18584452,"url":"https://github.com/ipfs-examples/js-ipfs-browser-exchange-files","last_synced_at":"2025-07-13T12:36:39.684Z","repository":{"id":104999397,"uuid":"376789389","full_name":"ipfs-examples/js-ipfs-browser-exchange-files","owner":"ipfs-examples","description":"Example of exchange files using JS-IPFS","archived":false,"fork":false,"pushed_at":"2025-05-01T07:36:17.000Z","size":1582,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-01T08:30:23.291Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ipfs-examples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-14T10:47:25.000Z","updated_at":"2025-05-01T07:36:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"ae38abfd-ddaa-40dd-96c9-aa6e07f25329","html_url":"https://github.com/ipfs-examples/js-ipfs-browser-exchange-files","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"ipfs-examples/example-fork-go-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-examples%2Fjs-ipfs-browser-exchange-files","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-examples%2Fjs-ipfs-browser-exchange-files/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-examples%2Fjs-ipfs-browser-exchange-files/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-examples%2Fjs-ipfs-browser-exchange-files/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipfs-examples","download_url":"https://codeload.github.com/ipfs-examples/js-ipfs-browser-exchange-files/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254473817,"owners_count":22077181,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T00:27:34.119Z","updated_at":"2025-05-16T05:33:09.466Z","avatar_url":"https://github.com/ipfs-examples.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://js.ipfs.io\" title=\"JS IPFS\"\u003e\n    \u003cimg src=\"https://ipfs.io/ipfs/Qme6KJdKcp85TYbLxuLV7oQzMiLremD7HMoXLZEmgo6Rnh/js-ipfs-sticker.png\" alt=\"IPFS in JavaScript logo\" width=\"244\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003e\u003cb\u003eExchange files with js-ipfs\u003c/b\u003e\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e\u003ci\u003eExchange files between the browser and other IPFS nodes\u003c/i\u003e\u003c/b\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/jlord/forkngo/gh-pages/badges/cobalt.png\" width=\"200\"\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/ipfs/js-ipfs/tree/master/docs\"\u003eExplore the docs\u003c/a\u003e\n  ·\n  \u003ca href=\"https://codesandbox.io/\"\u003eView Demo\u003c/a\u003e\n  ·\n  \u003ca href=\"https://github.com/ipfs-examples/js-ipfs-examples/issues\"\u003eReport Bug\u003c/a\u003e\n  ·\n  \u003ca href=\"https://github.com/ipfs-examples/js-ipfs-examples/issues\"\u003eRequest Feature/Example\u003c/a\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [About The Project](#about-the-project)\n- [Getting Started](#getting-started)\n  - [Pre requisites](#pre-requisites)\n  - [Installation and Running example](#installation-and-running-example)\n- [Usage](#usage)\n  - [Step-by-step instructions](#step-by-step-instructions)\n  - [1. Install `go-ipfs` or `js-ipfs`](#1-install-go-ipfs-or-js-ipfs)\n  - [2. Make your daemons listen on WebSockets](#2-make-your-daemons-listen-on-websockets)\n  - [3. Start the app](#3-start-the-app)\n  - [4. Dial to a node using WebSockets (your desktop ones)](#4-dial-to-a-node-using-websockets-your-desktop-ones)\n  - [5. Transfer files between all of your nodes!](#5-transfer-files-between-all-of-your-nodes)\n- [Going to production?](#going-to-production)\n  - [Use your own `@libp2p/webrtc-star` signalling server](#use-your-own-libp2pwebrtc-star-signalling-server)\n- [References](#references)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n- [Want to hack on IPFS?](#want-to-hack-on-ipfs)\n\n## About The Project\n\n- Read the [docs](https://github.com/ipfs/js-ipfs/tree/master/docs)\n- Look into other [examples](https://github.com/ipfs-examples/js-ipfs-examples) to learn how to spawn an IPFS node in Node.js and in the Browser\n- 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\n- Visit https://dweb-primer.ipfs.io to learn about IPFS and the concepts that underpin it\n- Head over to https://proto.school to take interactive tutorials that cover core IPFS APIs\n- Check out https://docs.ipfs.io for tips, how-tos and more\n- See https://blog.ipfs.io for news and more\n- Need help? Please ask 'How do I?' questions on https://discuss.ipfs.io\n\n## Getting Started\n\n### Pre requisites\n\nMake sure you have installed all of the following prerequisites on your development machine:\n\n- Git - [Download \u0026 Install Git](https://git-scm.com/downloads). OSX and Linux machines typically have this already installed.\n- Node.js - [Download \u0026 Install Node.js](https://nodejs.org/en/download/) and the npm package manager.\n- IPFS Daemon - [Install js-ipfs](https://github.com/ipfs/js-ipfs) or [Download \u0026 Install IPFS Desktop](https://docs.ipfs.io/install/ipfs-desktop/) that will run the go version of IPFS or head over to https://dist.ipfs.io/#go-ipfs and hit the \"Download go-ipfs\" button. Extract the archive and read the instructions to install.\n\n### Installation and Running example\n\n```console\n\u003e npm install\n\u003e npm start\n```\n\nNow open your browser at `http://localhost:8888`\n\n## Usage\n\nThis tutorial will help you exchange files between browser nodes and go-ipfs or js-ipfs nodes!\n\n**Note:** As `js-ipfs@0.41.x` currently doesn't support DHT peer discovery, the peer from which you are fetching data should be within the reach (local or in public IP) of the browser node.\n\nThat being said, we will explain how to circumvent these caveats and once they are fixed, we'll update the tutorial as well.\n\nThe goal of this tutorial is to create a simple application with an IPFS node that dials to other instances using WebRTC, and at the same time dial and transfer files from a browser IPFS node using WebSockets as the transport.\n\n```\n┌──────────────┐                ┌──────────────┐\n│   Browser    │ libp2p(WebRTC) │   Browser    │\n│              │◀──────────────▶│              │\n└──────────────┘                └──────────────┘\n       ▲                                  ▲\n       │WebSockets              WebSockets│\n       │        ┌──────────────┐          │\n       │        │   Desktop    │          │\n       └───────▶│   Terminal   │◀─────────┘\n                └──────────────┘\n```\n\n### Step-by-step instructions\n\nHere's what we are going to be doing:\n\n1. Install a `go-ipfs` or `js-ipfs` node in your machine\n2. Make your daemons listen on WebSockets\n3. Start a `@libp2p/webrtc-star` signalling server\n4. Start the app\n5. Dial to a node using WebSockets (your desktop ones)\n6. Transfer files between all of your nodes!\n\nJust follow the instructions below and it will be up and running in no time! At the end of this tutorial you should have something like this:\n\n![](img/goal.png)\n\n### 1. Install `go-ipfs` or `js-ipfs`\n\nIf you already have `go-ipfs` or `js-ipfs` installed in your machine, you can skip this step. Otherwise, read on.\n\nThis tutorial works with either `go-ipfs` or `js-ipfs`, so you can install one of your choosing.\n\n`go-ipfs` can be installed via its binary [here](https://ipfs.io/ipns/dist.ipfs.io/#go-ipfs). Alternatively, you can follow the install instructions in [ipfs/go-ipfs](https://github.com/ipfs/go-ipfs#install).\n\n`js-ipfs` requires you to have [node and npm](https://www.npmjs.com/get-npm) installed. Then, you simply run:\n\n```sh\n\u003e npm install --global ipfs\n```\n\nThis will alias `jsipfs` on your machine; this is to avoid issues with `go-ipfs` being called `ipfs`.\n\nAt this point, you should have either `js-ipfs` or `go-ipfs` running. Now, initialize it:\n\n```sh\n\u003e ipfs init\n# or\n\u003e jsipfs init\n```\n\nThis will set up an IPFS repo in your home directory.\n\n### 2. Make your daemons listen on WebSockets\n\nNow you need to edit your `config` file, the one you just set up with `{js}ipfs init`. It should be in either `~/.jsipfs/config` or `~/.ipfs/config`, depending on whether you're using JS or Go.\n\n**Note:** `js-ipfs` sets up a websocket listener by default, so if you're using the JS implementation you can skip this and just start the daemon.\n\nSince websockets support is currently not on by default, you'll need to add a WebSockets address manually. Look into your config file to find the `Addresses` section:\n\n```json\n\"Addresses\": {\n  \"Swarm\": [\n    \"/ip4/0.0.0.0/tcp/4002\"\n  ],\n  \"API\": \"/ip4/127.0.0.1/tcp/5002\",\n  \"Gateway\": \"/ip4/127.0.0.1/tcp/9090\"\n}\n```\n\nAdd the `/ip4/127.0.0.1/tcp/4003/ws` entry to your `Swarm` array. Now it should look like this:\n\n```json\n\"Addresses\": {\n  \"Swarm\": [\n    \"/ip4/0.0.0.0/tcp/4002\",\n    \"/ip4/127.0.0.1/tcp/4003/ws\"\n  ],\n  \"API\": \"/ip4/127.0.0.1/tcp/5002\",\n  \"Gateway\": \"/ip4/127.0.0.1/tcp/9090\"\n}\n```\n\nSave the file and it should be able to listen on Websockets. We're ready to start the daemon.\n\n```sh\n\u003e ipfs daemon\n# or\n\u003e jsipfs daemon\n```\n\nYou should see the Websocket address in the output:\n\n```sh\nInitializing daemon...\nSwarm listening on /ip4/127.0.0.1/tcp/4001\nSwarm listening on /ip4/127.0.0.1/tcp/4003/ws\nSwarm listening on /ip4/192.168.10.38/tcp/4001\nSwarm listening on /ip4/192.168.10.38/tcp/4003/ws\nAPI server listening on /ip4/127.0.0.1/tcp/5001\nGateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080\nDaemon is ready\n```\n\nCheck the `/ws` in line 5, that means it is listening. Cool.\n\n### 3. Start the app\n\nWe'll need to bundle the dependencies to run the app. Let's do it:\n\n```sh\n\u003e npm run build\n...\n\u003e npm start\n```\n\nNow go to http://127.0.0.1:8888 in a modern browser and you're on!\n\n### 4. Dial to a node using WebSockets (your desktop ones)\n\nMake sure you have a daemon running. If you don't, run:\n\n```sh\n\u003e ipfs daemon\n# or\n\u003e jsipfs daemon\n```\n\nOpen another terminal window to find the websocket addresses that it is listening on:\n\n```sh\n\u003e ipfs id\n# or\n\u003e jsipfs id\n```\n\nIt should look like this: `/ip4/127.0.0.1/tcp/4003/ws/ipfs/\u003cyour_peer_id\u003e`.\n\nCopy and paste the _multiaddr_ to connect to that peer:\n\n![](img/connect-1.png)\n\nCheck that you got connected:\n\n![](img/connect-2.png)\n\n\u003e It only works on localhost environments because of a restriction with WebCrypto where it will not load in a page unless that page is loaded over https, or the page is served from localhost: [libp2p/js-libp2p-crypto#105][js-libp2p-crypto#105]\n\n[js-libp2p-crypto#105]: https://github.com/libp2p/js-libp2p-crypto/issues/105\n\n### 5. Transfer files between all of your nodes!\n\nNow you can add files through the CLI with:\n\n```sh\n\u003e ipfs add \u003cfile\u003e\n# or\n\u003e jsipfs add \u003cfile\u003e\n```\n\nCopy and paste the _multihash_ and fetch the file in the browser!\n\n![](img/fetch.png)\n\nYou can also open two browser tabs, drag and drop files in one of them, and fetch them in the other!\n\nBut the coolest thing about this tutorial is `pubsub`! You can open two tabs that will share files through workspaces named after the url. Try opening two tabs with the following url:\n\n```\nhttp://127.0.0.1:12345/#file-exchange\n# You can substitute `file-exchange` with anything you like, just make sure the two tabs are in the same workspace.\n```\n\nNow every file that you upload in one tab will appear in the other! You can even open a new tab in that workspace and it will sync the files that were added before!\n\n![](img/pubsub.png)\n\n_For more examples, please refer to the [Documentation](#documentation)_\n\n## Going to production?\n\nThis example uses public webrtc-star servers. These servers should be used for experimenting and demos, they **MUST** not be used in production as there is no guarantee on availability.\n\n### Use your own `@libp2p/webrtc-star` signalling server\n\nThis server allows the two browser nodes to talk to each other by doing the initial handshake and network introductions.\n\nFirst install the `@libp2p/webrtc-star-signalling-server` module globally:\n\n```sh\n\u003e npm install -g @libp2p/webrtc-star-signalling-server\n```\n\nThis will give you the `webrtc-star` command. Use this to start a signalling server:\n\n```sh\n\u003e webrtc-star\n```\n\nBy default it will listen to all incoming connections on port 13579. Override this with the `--host` and/or `--port` options. That is, the following multiaddr: `/ip4/127.0.0.1/tcp/13579/wss/p2p-webrtc-star`.\n\nYou should add your signalling server in the IPFS config swarm addresses, so that you listen for new connections through it.\n\n## References\n\n- Documentation:\n  - [IPFS CONFIG](https://github.com/ipfs/js-ipfs/blob/master/docs/CONFIG.md)\n  - [MISCELLANEOUS](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/MISCELLANEOUS.md)\n  - [FILES](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md)\n  - [SWARM](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/SWARM.md)\n  - [PUBSUB](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/PUBSUB.md)\n  - [LIBP2P CONFIG](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md)\n- Tutorials:\n  - [Regular File API](https://proto.school/regular-files-api)\n  - [libp2p](https://proto.school/introduction-to-libp2p)\n\n## Documentation\n\n- [Config](https://docs.ipfs.io/)\n- [Core API](https://github.com/ipfs/js-ipfs/tree/master/docs/core-api)\n- [Examples](https://github.com/ipfs-examples/js-ipfs-examples)\n- [Development](https://github.com/ipfs/js-ipfs/blob/master/docs/DEVELOPMENT.md)\n- [Tutorials](https://proto.school)\n\n## Contributing\n\nContributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\n1. Fork the IPFS Project\n2. Create your Feature Branch (`git checkout -b feature/amazing-feature`)\n3. Commit your Changes (`git commit -a -m 'feat: add some amazing feature'`)\n4. Push to the Branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## Want to hack on IPFS?\n\n[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)\n\nThe IPFS implementation in JavaScript needs your help! There are a few things you can do right now to help out:\n\nRead 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).\n\n- **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\n- **Look at the [IPFS Roadmap](https://github.com/ipfs/roadmap)** This are the high priority items being worked on right now\n- **Perform code reviews** More eyes will help\n  a. speed the project along\n  b. ensure quality, and\n  c. reduce possible future bugs.\n- **Add tests**. There can never be enough tests.\n- **Join the [Weekly Core Implementations Call](https://github.com/ipfs/team-mgmt/issues/992)** it's where everyone discusses what's going on with IPFS and what's next\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipfs-examples%2Fjs-ipfs-browser-exchange-files","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipfs-examples%2Fjs-ipfs-browser-exchange-files","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipfs-examples%2Fjs-ipfs-browser-exchange-files/lists"}