New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using IPFS with electron (or muon) #256

Open
daviddias opened this Issue Aug 29, 2017 · 9 comments

Comments

Projects
None yet
4 participants
@daviddias
Member

daviddias commented Aug 29, 2017

It was raised to my attention that there have been some questions on the state of IPFS in Electron. I thought I would compile my notes and the information I shared in the last IPFS All Hands as it might be used by several members of the community.

If you are new to Electron or Muon, they are both open source frameworks that enable you to create native desktop applications that are independent of the OS (as long as it is Linux, Windows or Mac) while using the familiar Web technologies that you know and love. Electron was the first and Muon is a fork designed to specially build browsers.

Both of these frameworks offer to contexts, the:

  • Main process - A process that runs inside a Node.js context. This means every Node.js core module is available for you to use, including the FileSystem and a regular Network Stack.
  • Renderer process - The process where the UI of the application runs. This has a very similar feel to a regular browser application.

Both of these processes are connected by an IPC channel (ipcMain and ipcRenderer) so that you can send messages back and forth.

Given all of this, what are the options today? They are:

  • 1) Using a go-ipfs daemon with js-ipfs-api from the Main process
  • 2) Using a go-ipfs daemon with js-ipfs-api from the Renderer process
  • 3) Using js-ipfs from the Main process Currently, it does not work and that is what the thread The road to Electron support covers.
  • 4) Using js-ipfs from the Renderer process

1) Using a go-ipfs daemon with js-ipfs-api from the Main process

Spawning a go-ipfs daemon from Node.js is quite easy today by using the ipfsd-ctl. This module lets you export two API, one to directly control the daemon, another to control the daemon using js-ipfs-api.

We use this mode on Station, the IPFS menu bar application. You can also learn how we spawn the node and interact with it on the init.js file.

2) Using a go-ipfs daemon with js-ipfs-api from the Renderer process

Very similar to the mode above, you can spawn a go-ipfs deamon through the Main process and then create a js-ipfs-api on the Renderer process to make requests to it.

Having to create the instance separately could feel a bit cumbersome, fortunately, there is a better way! Electron supports a way to call Main process modules or instances directly from the Renderer process by automatically creating an RPC for them using the Remote API. You are able to create the same instance as 1) and then pass a reference to the Renderer process without having to actually do instantiation on the Renderer process.

This is how orbit-electron has been working since the beginning https://github.com/orbitdb/orbit-electron

3) Using js-ipfs from the Main process

Currently, it does not work and that is what the thread The road to Electron support covers.

The reason why is due to the use of some Native dependencies in js-ipfs that do not get compiled cleanly by Electron's own Node.js version. We already started the process of fixing or replacing some of this dependencies but more work needs to be done. If you would like to help, make sure to check The road to Electron support.

Update: With js-ipfs 0.29 and Electron 2.0, you can now run js-ipfs on the Main Process too! See an example here https://github.com/ipfs/js-ipfs/tree/master/examples/run-in-electron.

4) Using js-ipfs from the Renderer process

You can use js-ipfs from the Renderer process. The simplest way is to just grab the dist version of js-ipfs and add it as a script to your Electron app, it will expose a Ipfs class for the context of your app just like loading IPFS through a Script tag.

This is own we approached the IPFS integration for the Brave browser as you can see in the prototype ipfs-shipyard/browser-laptop#1

@daviddias

This comment has been minimized.

Member

daviddias commented Sep 7, 2017

Quick update! For everyone looking to use go-ipfs in Windows with Electron, @thisconnect has shipped compatibility in js-ipfsd-ctl. See:

@daviddias

This comment has been minimized.

Member

daviddias commented Dec 5, 2017

Update here, @hacdias just refreshed IPFS Station with bug fixes, features, and all new look! Check out https://github.com/ipfs-shipyard/station to see an IPFS Application with electron.

@daviddias

This comment has been minimized.

Member

daviddias commented May 28, 2018

Update: 3) is now supported as well with js-ipfs 0.29 and Electron 2.0. See example here https://github.com/ipfs/js-ipfs/tree/master/examples/run-in-electron

@koalalorenzo

This comment has been minimized.

koalalorenzo commented May 28, 2018

As we are developing https://github.com/Siderus/Orion around js-ipfs-api, it would be a huge improvement for us to switch to js-ipfs. One year ago it was too basic and lacking a lot of things needed (I don't remember now which one, sorry).

Where does the implementation stand when compared to go-ipfs + js-ipfs-api? Do we have most of the functionalities? \o/

@vaibhav6233m

This comment has been minimized.

vaibhav6233m commented Jun 18, 2018

I am also developing an electron app using js-ipfs inside the main electron process in "electron": "^1.8.6". It works on Linux, need to check on Mac and Windows.
Recently I found this implementation https://github.com/AkashaProject/ipfs-connector.

I was wondering which one is better, js-ipfs or ipfs-connector ?

I have the same question which @koalalorenzo is asking

Where does the implementation stand when compared to go-ipfs + js-ipfs-api? Do we have most of the functionalities? \o/

@Mr0grog

This comment has been minimized.

Mr0grog commented Jun 18, 2018

I was wondering which one is better, js-ipfs or ipfs-connector ?

@vaibhav6233m I’m not super familiar with ipfs-connector, but at a glance, it actually looks a little more similar to js-ipfsd-ctl, which downloads & installs the IPFS binary for you and gives you a few methods for starting/stopping it and then a standard API for interacting with it. ipfs-connector looks like it only supports go-ipfs, while js-ipfsd-ctl supports both go-ipfs and js-ipfs (but that does make starting a bit more complicated—you have to choose which kind of IPFS node you want).

Where does the [js-ipfs] implementation stand when compared to go-ipfs + js-ipfs-api? Do we have most of the functionalities?

I’d say js-ipfs is still a bit behind if you’re looking for full functionality. For example, the pin API and MFS aren’t done yet. (But both are really close!)

If you don’t need those, you probably want to pay close attention to these issues on making js-ipfs less error-prone:

@vaibhav6233m

This comment has been minimized.

vaibhav6233m commented Jun 19, 2018

@Mr0grog Thanks a lot for your comments.

In my case, I wanted to use the libp2p stack using the IPFS instance such as functions like dialProtocol and handle to communicate between the nodes using their nodeID (If that is how it is supposed to be used).

In the IPFS documentation this is mentioned.

libp2p. Every IPFS instance also exposes the libp2p SPEC at ipfs.libp2p. The formal interface for this SPEC hasn't been defined by you can find documentation at its implementations:

But I could only find the references to start() and stop() method using ipfs.libp2p, not the ones I want to use.
I closely looked inside the IPFS instance to find a way to access libp2p functionality and found that there are some libp2p methods under ipfs._libp2pNode.

I tried to use those also but still facing some issues. I am not sure if it is the proper way to access them.

Is it the same while using the js-ipfsd-ctl?
I know this is not the place to ask these issues.
I thought you might guide me in the right direction. Thanks a lot in advance.

@Mr0grog

This comment has been minimized.

Mr0grog commented Jun 21, 2018

Yeah, it would be great if you moved this to https://discuss.ipfs.io.

I wanted to use the libp2p stack using the IPFS instance… to communicate between the nodes using their nodeID

First, can you accomplish what you want with pubsub instead of libp2p? If yes, you can use that through any of the libraries. Otherwise, libp2p usage over the API can be complicated.

there are some libp2p methods under ipfs._libp2pNode

ipfs._libp2pNode is an instance of js-libp2p, so you can use it. I don't know if that's really recommended, though. Others like @diasdavid can say better.

Again, if you want to ask more about those, you should probably move this to https://discuss.ipfs.io.

@vaibhav6233m

This comment has been minimized.

vaibhav6233m commented Jun 21, 2018

@Mr0grog Thanks a lot again. I'll be posting the technical issues to https://discuss.ipfs.io/ .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment