We have been working on a react-native application involving complex use-cases such as XMPP based textual group (MUC) chat, WebRTC/SIP based Audio conferencing and several other integrations with third party services. Given varied and relatively high integration points, we needed to scout and use many third party components, APIs and libraries. This post answers questions related to using off-the-shelf nodejs modules (through NPM) in react native applications.
Can you use Node Modules in React Native?
In theory, YES; In reality, as it stands today, (in most of the cases) NO. Try using https://www.npmjs.com/package/hello-world-classic – this works; but try using https://www.npmjs.com/package/sax – this wont!
Why is that?
While node modules can be used simply by doing npm install <module name>, very high percentage (can’t quantify at this moment but will try and do so soon) of modules simply won’t work since they depend on many core node modules e.g. stream, fs, child_process etc. which are not available within JS engine of React Native.
Are there any workarounds?
Yes and No. Before explaining why I say that, let me try to first touch upon potential workarounds.
Ideally the solution would have been to have a react native lib which implements core node modules. In absence of such a lib, the option is to have shimming libs or modules developed by third parties which can be used with React Native.
A project called Browserify has already done this and has become a pretty stable project by all accounts. In React Native space, some developers have tried to create shims for core node modules. There is a module called rn-nodeify (https://github.com/mvayngrib/rn-nodeify) which automagically provides the shimming.
Are these workarounds dependable?
Based on our observation and experience, the answer is Not really. rn-nodeify does a good job in resolving dependencies in some cases but there are certain dependencies which are unfulfilled and many a times that ends up becoming a showstopper.
Net net we do not recommend depending on these workarounds for any serious app development activity.
How do we deal with this situation?
First of all, if you are at a planning phase of a react native project, assume more or less zero reusability of existing node modules; you would be lucky to get some working but treat it as a bonus.
For now, following are the more safer options –
- Rewrite the portion of node module by decoupling the core modules. Carefully look at recursive dependencies to make sure that the decoupling is feasible through and through.
- Use Native Module technique (https://facebook.github.io/react-native/docs/native-modules-ios.html) to use native libraries/components.
A react native bug https://github.com/facebook/react-native/issues/4968 is symptomatically similar to what you would see when you encounter the problem described in this post. However if you are running into issues due to core modules, any remedies given in context of the aforementioned bug will not help.