|
| 1 | +# Using JS IPFS in the Browser |
| 2 | + |
| 3 | +JS IPFS is the implementation of IPFS protocol in JavaScript. It can run on any |
| 4 | +evergreen browser, inside a service or web worker, browser extensions, Electron and in Node.js. |
| 5 | + |
| 6 | +**This document provides key information about running JS IPFS in the browser. |
| 7 | +Save time and get familiar with common caveats and limitations of the browser context.** |
| 8 | + |
| 9 | +## Limitations of the Browser Context |
| 10 | + |
| 11 | +- Transport options are 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). |
| 12 | + |
| 13 | + This means JS IPFS running in the browser is limited to Web APIs available on a web page. |
| 14 | + There is no access to raw TCP sockets nor low level UDP, only WebSockets and WebRTC. |
| 15 | + |
| 16 | +- 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. |
| 17 | + |
| 18 | + This means JS IPFS needs to run within Secure Context (HTTPS or localhost). |
| 19 | + JS IPFS running on HTTPS website requires Secure WebSockets (TLS) and won't work with unencrypted one. |
| 20 | + [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) not being available at all. |
| 21 | + |
| 22 | +- [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) is not available in JS IPFS yet. |
| 23 | + |
| 24 | + [We are working on it](https://github.com/ipfs/js-ipfs/pull/1994). For now, the discovery and connectivity to other peers is achieved with a mix of rendezvous and |
| 25 | + relay servers, delegated peer/content routing and preload servers. |
| 26 | + |
| 27 | + |
| 28 | +## Addressing Limitations |
| 29 | + |
| 30 | +We provide a few additional components useful for running JS IPFS in the browser: |
| 31 | + |
| 32 | +- [libp2p-websocket-star](https://github.com/libp2p/js-libp2p-websocket-star/) - incorporates both a transport and a discovery service that is facilitated by the custom rendezvous server available in the repo. |
| 33 | + - Instructions on enabling `websocket-star` in js-ipfs config can be found [here](https://github.com/ipfs/js-ipfs#is-there-a-more-stable-alternative-to-webrtc-star-that-offers-a-similar-functionality). |
| 34 | + - Make sure to [run your own rendezvous server](https://github.com/libp2p/js-libp2p-websocket-star/#usage-1). |
| 35 | +- [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 |
| 36 | + - Instructions on enabling `webrtc-star` in js-ipfs config can be found [here](https://github.com/ipfs/js-ipfs#how-to-enable-webrtc-support-for-js-ipfs-in-the-browser). |
| 37 | + - Make sure to [run your own rendezvous server](https://github.com/libp2p/js-libp2p-webrtc-star#rendezvous-server-aka-signalling-server). |
| 38 | +- [libp2p-webrtc-direct](https://github.com/libp2p/js-libp2p-webrtc-direct) - a WebRTC transport that doesn't require the set up a signalling server. |
| 39 | + - Caveat: you can only establish Browser to Node.js and Node.js to Node.js connections. |
| 40 | + |
| 41 | +**Note:** those are semi-centralized solutions. We are working towards replacing `*-star` with and 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). |
| 42 | + |
| 43 | +You can find detailed information about running js-ipfs [here](https://github.com/ipfs/js-ipfs#table-of-contents). |
| 44 | + |
| 45 | +## Best Practices |
| 46 | + |
| 47 | +- Configure nodes for using self-hosted `*-star` signaling and transport service. When in doubt, use WebSockets ones. |
| 48 | +- Run your own instance of `*-star` signaling service. |
| 49 | + The default ones are under high load and should be used only for tests and development. |
| 50 | +- Make sure content added to js-ipfs running in the browser is persisted/cached somewhere on regular IPFS daemon |
| 51 | + - Manually `pin` or preload CIDs of interest with `refs -r` beforehand. |
| 52 | + - Preload content on the fly using [preload](https://github.com/ipfs/js-ipfs#optionspreload) feature and/or |
| 53 | + configure [delegated routing](https://github.com/ipfs/js-ipfs#configuring-delegate-routers). |
| 54 | + - Avoid public instances in production environment. Make sure preload and delegate nodes used in config are self-hosted and under your control (expose a subset of go-ipfs APIs via reverse proxy such as Nginx). |
| 55 | + |
| 56 | +## Code Examples |
| 57 | + |
| 58 | +Prebuilt bundles are available, using JS IPFS in the browser is as simple as: |
| 59 | + |
| 60 | +```js |
| 61 | +<script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script> |
| 62 | +<script> |
| 63 | +document.addEventListener('DOMContentLoaded', async () => { |
| 64 | + const node = await Ipfs.create() |
| 65 | + const results = await node.add('=^.^= meow meow') |
| 66 | + const cid = results[0].hash |
| 67 | + console.log('CID created via ipfs.add:', cid) |
| 68 | + const data = await node.cat(cid) |
| 69 | + console.log('Data read back via ipfs.cat:', data.toString()) |
| 70 | +}) |
| 71 | +</script> |
| 72 | +``` |
| 73 | + |
| 74 | +More advanced examples and tutorials can be found in [`/examples`](https://github.com/ipfs/js-ipfs/tree/master/examples#js-ipfs-examples-and-tutorials) |
0 commit comments