How to use HiveJs (or other modules referencing core Node.js modules) on React Native

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@stoodkev·
0.000 HBD
How to use HiveJs (or other modules referencing core Node.js modules) on React Native
![image.png](https://files.peakd.com/file/peakd-hive/stoodkev/C3S6phs5-image.png)

As some of you may know, I am developing a Hive Keychain App for mobile using React Native (RN). @revo asked me how I managed to use Hive related modules on RN.

Although RN uses Javascript, some npm modules won't work directly because they use Node.js core modules such as `assert` and `crypto`.

It's a bit tedious to make it work, but I truly hope to see more mobile Application in our ecosystem, so I'm writing this tutorial hoping it will be of some help.

**Babel to the rescue!**

We will use Babel and `rewrite-require` preset to rewrite some of these modules to use React Native or browserified packages instead. 

Let's see step by step how this is working out on a new project.

## Step 1 : Create a new project

I will assume you already have your environment setup and that we are making a classic React Native project (no expo) :

```
npx react-native init [ProjectName]
```

## Step 2 : Add Hivejs

Run 
``` 
npm i @hiveio/hive-js --save
 ```

Let's try it out, on App.js, add the following lines after the imports :

```
import hivejs from '@hiveio/hive-js'

(async function () {
  console.log(await hivejs.api.getAccountsAsync(['stoodkev']));
})();
```

Try to run the App and bim! Error!

```
error: Error: Unable to resolve module `assert` from `node_modules/@hiveio/hive-js/lib/auth/memo.js`: assert could not be found within the project.
```

That's because React Native has no idea what `assert` or `crypto` modules are, since they are Node.js core modules.

## Step 3 : Babel Config

Find your babel file, `babel.config.js`. 
Note that the name might be slightly different such as `.babelrc` or `.babel-cli`.

Add the following lines to the existing config : 

```
sourceMaps: true,
plugins: [
        [
            'rewrite-require',
            {
                aliases: {
                    crypto: 'react-native-crypto',
                    constants: 'constants-browserify',
                    dns: 'node-libs-browser/mock/dns',
                    domain: 'domain-browser',
                    fs: 'node-libs-browser/mock/empty',
                    http: 'stream-http',
                    https: 'https-browserify',
                    net: 'node-libs-browser/mock/net',
                    os: 'os-browserify/browser',
                    path: 'path-browserify',
                    pbkdf2: 'react-native-pbkdf2-shim',
                    querystring: 'querystring-es3',
                    stream: 'stream-browserify',
                    _stream_duplex: 'readable-stream/duplex',
                    _stream_passthrough: 'readable-stream/passthrough',
                    _stream_readable: 'readable-stream/readable',
                    _stream_transform: 'readable-stream/transform',
                    _stream_writable: 'readable-stream/writable',
                    sys: 'util',
                    timers: 'timers-browserify',
                    tls: 'node-libs-browser/mock/tls',
                    tty: 'tty-browserify',
                    vm: 'vm-browserify',
                    zlib: 'browserify-zlib',
                },
                throwForNonStringLiteral: true,
            },
        ],
    ],
```

Install the following dependencies : 

```
npm i --save babel-plugin-rewrite-require events assert react-native-crypto stream react-native-randombytes vm-browserify process
```

Also add manually this dependency in `package.json` then `npm install` :

```
"react-native-pbkdf2-shim": "git+https://git@github.com/wswoodruff/react-native-pbkdf2-shim.git"
```

## Step 4 : Add globals

If you try to run the code now you should see this error : 

```
ExceptionsManager.js:76 Error: Buffer not supported in this environment. Use Node.js or Browserify for browser support.
```

Create a `global.js` file on the root of the project : 

```
// Inject node globals into React Native global scope.
global.Buffer = require('buffer').Buffer;
global.process = require('process');
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';

// Needed so that 'stream-http' chooses the right default protocol.
global.location = {
  protocol: 'file:',
};

// Don't do this in production. You're going to want to patch in
// https://github.com/mvayngrib/react-native-randombytes or similar.
global.crypto = {
  getRandomValues(byteArray) {
    for (let i = 0; i < byteArray.length; i++) {
      byteArray[i] = Math.floor(256 * Math.random());
    }
  },
};
```

And import it from `App.js` :

```
import './global.js'
```

## Step 5: Voila!

HiveJs should now be working and you should see my account info in your debugger. 

If you are still getting errors, try cleaning the modules :

```
rm -rf node_modules && npm install && npx jetify
```

I uploaded [my code](https://github.com/stoodkev/react-native-hivejs-example/tree/master) to Github for reference, I hope this will help future Hive mobile devs ;)

If you have questions or encounter some issues, don't hesitate to ask me questions in the comment section.

Hive on! 


---

@stoodkev
Hive Keychain PO
If you find my work valuable, please consider voting for my [Witness](https://hivesigner.com/sign/account-witness-vote?witness=stoodkev&approve=1)

👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,