Skip to content
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

React Native support #2136

Closed
achingbrain opened this issue Oct 6, 2023 · 13 comments · Fixed by #2540
Closed

React Native support #2136

achingbrain opened this issue Oct 6, 2023 · 13 comments · Fixed by #2540
Assignees

Comments

@achingbrain
Copy link
Member

achingbrain commented Oct 6, 2023

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:

Demo:

@achingbrain achingbrain added the need/triage Needs initial labeling and prioritization label Oct 6, 2023
@maschad maschad self-assigned this Oct 12, 2023
@maschad maschad added exploration and removed need/triage Needs initial labeling and prioritization labels Oct 12, 2023
@maschad
Copy link
Member

maschad commented Nov 7, 2023

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.

@anistark
Copy link

anistark commented Nov 14, 2023

Is this supported now for React Native in iOS ?

Even better if expo can be supported.

@maschad
Copy link
Member

maschad commented Nov 15, 2023

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

@achingbrain
Copy link
Member Author

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
Copy link
Member Author

☝️ cc: @shamilovtim

@shamilovtim
Copy link

shamilovtim commented Dec 11, 2023

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.

@achingbrain
Copy link
Member Author

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.

@shamilovtim
Copy link

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
Copy link

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.

@boorad
Copy link

boorad commented Dec 28, 2023

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.

@maschad
Copy link
Member

maschad commented Jan 9, 2024

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

  • TCP working
  • WebRTC workling

@sleep9
Copy link

sleep9 commented Feb 27, 2024

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 ipfs-shipyard/js-libp2p-react-native#7

@dhuseby
Copy link
Contributor

dhuseby commented May 7, 2024

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

maschad added a commit to maschad/js-libp2p that referenced this issue May 11, 2024
achingbrain pushed a commit that referenced this issue May 16, 2024
Update React Native instructions in config

Closes #2136
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🎉Done
Development

Successfully merging a pull request may close this issue.

7 participants