js-libp2p icon indicating copy to clipboard operation
js-libp2p copied to clipboard

React Native support

Open achingbrain opened this issue 2 years ago • 12 comments

We'd love to officially support running on React Native.

The requirements for this would be:

  1. The unit test suite running in CI
  2. Lightweight - e.g. the developer should not have to install extra applications or sign EULAs if possible

There's been some preliminary support added to aegir for running tests under Android but I'm not sure what the current state of the art is in automated testing.

A preliminary pass might just be to get a simple demo react-native app running libp2p working. This might involve a list of required changes to modules to polyfill or replace APIs that do not exist/are buggy/incomplete in React Native.

If it helps to reduce the scope, perhaps a stand-alone repo could be tackled first to prove it out instead of the js-libp2p monorepo.

This was discussed briefly at the js-colo in NYC last week.

Refs:

  • https://github.com/ipfs/aegir/issues/437
  • https://github.com/ipfs/aegir/pull/777

Demo:

  • https://github.com/maschad/libp2p-react-native

achingbrain avatar Oct 06 '23 13:10 achingbrain

I've been putting together a demo that hopefully we can showcase at libp2p Day there's still some work to do, as @achingbrain mentioned a bulk of the work has been polyfill-ing and adapting modules.

the goal is to hopefully have two mobile nodes connected via websockets and/or a laptop as well for bonus.

maschad avatar Nov 07 '23 16:11 maschad

Is this supported now for React Native in iOS ?

Even better if expo can be supported.

anistark avatar Nov 14 '23 14:11 anistark

Not yet @anistark I will update this issue once either platform is supported, for now you can track progress at https://github.com/maschad/libp2p-react-native

maschad avatar Nov 15 '23 07:11 maschad

The latest patch release of js-libp2p & supporting modules have shipped with some fixes for running under react-native.

There's a new demo app at https://github.com/ipfs-shipyard/js-libp2p-react-native which uses Expo to build a simple app with a running libp2p node.

It currently supports WebSocket and tcp transports. WebRTC should also work via react-native-webrtc but I'm having some problems - WebRTCModule being passed to new NativeEventEmitter here is null which probably means the demo is missing some config - PRs are gratefully accepted.

Please try it out and let us know how you get on.

achingbrain avatar Dec 11 '23 12:12 achingbrain

☝️ cc: @shamilovtim

achingbrain avatar Dec 11 '23 13:12 achingbrain

The latest patch release of js-libp2p & supporting modules have shipped with some fixes for running under react-native.

There's a new demo app at https://github.com/ipfs-shipyard/js-libp2p-react-native which uses Expo to build a simple app with a running libp2p node.

It currently supports WebSocket and tcp transports. WebRTC should also work via react-native-webrtc but I'm having some problems - WebRTCModule being passed to new NativeEventEmitter here is null which probably means the demo is missing some config - PRs are gratefully accepted.

Please try it out and let us know how you get on.

Reviewed the demo project, looks like what i'd expect.

  • "react-native" directives in package.json: this is what we're simulating when using our custom metro resolver to point each IPLD dependency to its esm bundle. we also do this for uint8arrays, it-, dag-, multiformats, progress-events etc. You can see the full list here: https://github.com/TBD54566975/web5-react-native-metro-config/blob/master/src/index.js. Once all of the packages have the "react-native" directive in their package.json we can remove a huge chunk of this custom resolver, if not the whole thing.
  • webcrypto polyfill: it's worth it to point out that this is a pure JS polyfill, which is slow. we use https://github.com/margelo/react-native-quick-crypto which is native node crypto (openssl).

I don't use the experimental "exports" support right now so this is the only part of your demo project I'm unsure about. The "react-native" directive is like a scalpel for us while the "exports" is a blunt hammer that caused more harm than good when I tried to use it.

shamilovtim avatar Dec 11 '23 19:12 shamilovtim

Thanks for taking a look.

"exports" is a blunt hammer that caused more harm than good when I tried to use it

I'm interested in what's still broken here, once I'd fixed up it-ws and a few libp2p modules it was pretty much plain sailing, though granted the dependency tree of the demo is quite small.

Certainly turning on exports map support will let you remove all of those custom directives.

I do wonder too, if react-native will turn it on by default in the future so it'd be good to get a head start on that.

webcrypto polyfill: it's worth it to point out that this is a pure JS polyfill,

Looking through the source code @peculiar/webcrypto doesn't do any crypto operations using JS, it uses node's crypto module internally which the demo then swaps out for react-native-quick-crypto.

achingbrain avatar Dec 11 '23 19:12 achingbrain

Certainly turning on exports map support will let you remove all of those custom directives.

My memory is a little foggy here but it caused a cascade of dependency incompatiblities. For instance, package A selects { exports: {'.' : node-esm.js } } while package B selects: { exports: { '.' : browser-esm.js }. There was no consistency in what package authors were putting in their exports. We still ended up needing to manually resolve packages and cherrypick bundles using the custom resolver, but it made the dependency resolution even more confusing. The react native directive on the other hand is asserting "yes this is the correct bundle to use with react native."

shamilovtim avatar Dec 11 '23 19:12 shamilovtim

Looking through the source code @peculiar/webcrypto doesn't do any crypto operations using JS, it uses node's crypto module internally which the demo then swaps out for react-native-quick-crypto.

Very nice. I actually had no idea this existed. I confused it with a different pure js polyfill (the msr one). That's pretty brilliant that they're using node crypto to polyfill webcrypto. I think I'll even bring this into our project.

shamilovtim avatar Dec 11 '23 22:12 shamilovtim

I'm not sure it's of interest here, but I need some crypto.subtle functions in RN, so I'm hacking on react-native-quick-crypto to add them.

boorad avatar Dec 28 '23 04:12 boorad

Given we have Websockets working 🥳 see https://github.com/ipfs-shipyard/js-libp2p-react-native the remaining work is get:

  • [ ] TCP working
  • [ ] WebRTC workling

maschad avatar Jan 09 '24 16:01 maschad

I would like to get WebRTC working in react-native. But I get the following error. Your javascript code tried to access a native module that doesn't exist in this development client.

Edit The above error is resolved by installing react-native-webrtc and its associated native modules, however still having some issues which can be seen here https://github.com/ipfs-shipyard/js-libp2p-react-native/issues/7

sleep9 avatar Feb 27 '24 21:02 sleep9

Action item: document which transports work and which ones don't to update the README and then close this.

dhuseby avatar May 07 '24 15:05 dhuseby