Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to set up web3.js (Ethereum JS API) with Create React Native App

How to set up web3.js with CRNA

This is a simple guide to get you started with using the Ethereum Javascript API (web3.js) with the Create React Native App project. This is not an in-depth guide.

TL;DR

If you are lazy and just want to get started, I have this project ready for you. It should work out-of-the-box.

Installation guide

  1. Make sure you have Node version 6 or later installed, if not, get it on the Node website

    node --version

  2. Install Create React Native App

    npm install -g create-react-native-app

  3. Use create-react-native-app to create the project boilerplate

    create-react-native-app my-app

  4. Install node-libs-browser

    npm install --save node-libs-browser

  5. Create a file called rn-cli.config.js on the root of the project and add the following code into it:

    const extraNodeModules = require('node-libs-browser');
    
    module.exports = {
      extraNodeModules,
    };
  6. Create a file called global.js on the root of the project and add the following code into it:

    // Inject node globals into React Native global scope.
    global.Buffer = require('buffer').Buffer;
    global.process = require('process');
    
    if (typeof btoa === 'undefined') {
      global.btoa = function (str) {
        return new Buffer(str, 'binary').toString('base64');
      };
    }
    
    if (typeof atob === 'undefined') {
      global.atob = function (b64Encoded) {
        return new Buffer(b64Encoded, 'base64').toString('binary');
      };
    }
    
  7. Import the global.js file into your App.js file

    import './global';
  8. Install babel-preset-es2015

    npm install --save-dev babel-cli babel-preset-es2015

  9. Now we can install the web3.js api

    npm install --save web3

  10. Require the API in your App.js file

    const Web3 = require('web3');
  11. Add the following code inside your React component in App.js to get started with consuming the API. The code will print information of the latest block on the console.

    componentWillMount() {
      const web3 = new Web3(
        new Web3.providers.HttpProvider('https://mainnet.infura.io/')
      );
    
      web3.eth.getBlock('latest').then(console.log)
    }
  12. Test it

    npm start

    or

    npm run ios

    or

    npm run android

For more examples on the API usage, visit the web3.js documentation.

For a project with all this setup ready, check out my repo.

@amitranjan14

This comment has been minimized.

Copy link

amitranjan14 commented Nov 2, 2017

Hi ,
Thanks for sharing the steps. Have you tried with web3 v 1.0?

Thanks and Regards
Amit

@craigcoles

This comment has been minimized.

Copy link

craigcoles commented Nov 2, 2017

Followed the instructions exactly, and couldn't get it to work 😢

@dougbacelar

This comment has been minimized.

Copy link
Owner Author

dougbacelar commented Nov 13, 2017

@amitranjan14 I am using the following version:

"web3": "^1.0.0-beta.24"

@dougbacelar

This comment has been minimized.

Copy link
Owner Author

dougbacelar commented Nov 13, 2017

@craigcoles
What error did you get?

@craigcoles

This comment has been minimized.

Copy link

craigcoles commented Nov 17, 2017

@dougbacelar We are not using CRNA, but we have a very similar setup.

Bundling `index.js`  [development, non-minified]  98.9% (1253/1260), failed.
error: bundling failed: Error: require() must have a single string literal argument
    at pushDependency (/Users/craigcoles/Projects/Test/node_modules/metro-bundler/src/JSTransformer/worker/extract-dependencies.js:39:13)
    at CallExpression (/Users/craigcoles/Projects/Test/node_modules/metro-bundler/src/JSTransformer/worker/extract-dependencies.js:50:9)
    at NodePath._call (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node (/Users/craigcoles/Projects/Test/node_modules/babel-traverse/lib/index.js:114:17)
@gabmontes

This comment has been minimized.

Copy link

gabmontes commented Nov 22, 2017

@tharzeez

This comment has been minimized.

Copy link

tharzeez commented Jan 25, 2018

its working, following the steps sequentially made the magic <3

and dont forget to add ./shim and ./global at the top of the import .. the first line should be these two

@craigcoles

This comment has been minimized.

Copy link

craigcoles commented Feb 2, 2018

@dougbacelar Managed to get this working without CRNA, and just using react-native init TestApp 👍

@kibagateaux

This comment has been minimized.

Copy link

kibagateaux commented Feb 16, 2018

@craigcoles Following the exact same steps, no difference at all except substituting create-react-native-app with react-native init?

@markspereira

This comment has been minimized.

Copy link

markspereira commented Mar 12, 2018

react-native-cli: 2.0.1
react-native: 0.54.1
node: 8.6.0
npm: 5.7.1
web3: 1.0.0-beta.30

I'm getting an error "undefined is not an object (evaluating 'root._')

@gornostal

This comment has been minimized.

Copy link

gornostal commented Apr 16, 2018

Few questions

  1. babel-cli babel-preset-es2015 must be only installed or should I make some changes to .babelrc?
  2. @tharzeez what ./shim are you talking about?
  3. rn-cli.config.js seems to be unused. Should I import it in App.js?
@datsoc

This comment has been minimized.

Copy link

datsoc commented Apr 23, 2018

Can't find variable: btoa in web3-providers-ws :(

@tharzeez

This comment has been minimized.

Copy link

tharzeez commented Apr 25, 2018

@gornostal i installed rn-nodeify to my project and followed these steps .

@GaspardPeduzzi

This comment has been minimized.

Copy link

GaspardPeduzzi commented Apr 26, 2018

Hi,
Thanks for the shared instructions. I tried in vain for a while using the latest version of web3 ("web3": "^ 1.0.0-beta.34") with react-native and I did not succeed even while following the steps one by one : I get the error "Can not find variable: btoa". I also tried to install rn-nodeify but I get the same thing. Would you know how to fix this problem?
Thank you in advance

@nacmonad

This comment has been minimized.

Copy link

nacmonad commented Apr 27, 2018

add this to global.js



if (typeof btoa === 'undefined') {
  global.btoa = function (str) {
    return new Buffer(str, 'binary').toString('base64');
  };
}

if (typeof atob === 'undefined') {
  global.atob = function (b64Encoded) {
    return new Buffer(b64Encoded, 'base64').toString('binary');
  };
}

its another method that should be w/ the node-libs-browser buffer

but im still stuck, i then get

requiring unknown module "undefine". if you are sure the module is there, try restarting Metro Bundler.

restarting does not help.

@GaspardPeduzzi

This comment has been minimized.

Copy link

GaspardPeduzzi commented Apr 28, 2018

@nacmonad It worked for me by following the steps and adding this in global.js, thanks a lot

@markspereira

This comment has been minimized.

Copy link

markspereira commented Jun 12, 2018

https://github.com/markspereira/react-native-web3-boilerplate I managed to get web3 1.0.0 working. For account creation I use 'ethereumjs-wallet' as it doesn't work with the web3 1.0.0 on react-native and that pretty much covers everything you would want to do.

@dougbacelar

This comment has been minimized.

Copy link
Owner Author

dougbacelar commented Jun 24, 2018

I created this ready-to-go project for people that are struggling with this.

Simply clone the project below and it should be working out-of-the-box.
https://github.com/dougbacelar/react-native-web3

Thanks everyone for the troubleshooting.

Special thanks to @nacmonad for explaining how to fix the btoa issue.

Note: I used yarn instead of npm this time.

@dougbacelar

This comment has been minimized.

Copy link
Owner Author

dougbacelar commented Jun 24, 2018

@markspereira just read your comment now, seems like we had the same idea 😃

Thanks for creating a boilerplate too 👍 , hope these repos will help other people.

@ccheu

This comment has been minimized.

Copy link

ccheu commented Jun 28, 2018

@dougbacelar, thanks for the boilerplate. I noticed that you use Expo in the package.json but did not use Expo's forked SDK for react native. When using Expo's forked SDK for react native, the package.json would look like this:
"react-native": "https://github.com/expo/react-native/archive/sdk-27.0.1.tar.gz",

When tried changing the package.json, deleted the entire node_modules folder and nom install, I get an error when I exp start and exp ios. The error says a module attempted to import the Node standard library module "crypto". It failed because React Native does not include the Node standard library. Have you tried?

@ortonomy

This comment has been minimized.

Copy link

ortonomy commented Jul 14, 2018

babel-preset-es2015 will have no effect unless it's added to .babelrc file?

if fact, adding babel-preset-es2015 causes react native to fail.

@0es

This comment has been minimized.

Copy link

0es commented Jul 21, 2018

Very helpful gist !!! Thanks a lot

@dancomanlive

This comment has been minimized.

Copy link

dancomanlive commented Aug 10, 2018

Does it work with Expo?

@madhavanmalolan

This comment has been minimized.

Copy link

madhavanmalolan commented Aug 23, 2018

How can we get this to work with Expo? It is unable to resolve 'crypto'

@ygirase

This comment has been minimized.

Copy link

ygirase commented Aug 30, 2018

We have not created the Expo project

We have created the react-native project using init command

Using the below react-native version:
"react": "16.2.0",
"react-native": "0.52.0",

After run in iOS getting below error
error: CONNECTION ERROR: Couldn't connect to node https://mainnet.infura.io/

@HuanDay

This comment has been minimized.

Copy link

HuanDay commented Sep 2, 2018

@ygirase https://mainnet.infura.io/ this is just an example one. You should generate you won infura keys with this api

@bcachain

This comment has been minimized.

Copy link

bcachain commented Sep 4, 2018

@ygirase I face some issues and it looks there is version issues
original
node: 10.xx
web3: 1.0 -- beta 35

current
node: 8.xx
web3: 1.0 -- beta 33

No idea why, but in latest web3 version, XMLHttpRequest has some issues to open a "infura" request. I didn't get much time to do future investigate, but please don't use latest version i suggest.

@sinchan

This comment has been minimized.

Copy link

sinchan commented Oct 4, 2018

FYI: At least for Web3 v1.0.0-beta 36, node-libs-browser doesn't work because it uses crypto-browserify which in turn relies on the Crypto WebAPI that isn't in the JavaScriptCore that react-native js is running in. You have to use the node-libs-react-native package and have to manually react-native link at least react-native-randombytes to get things to work.

In order to make this work on Expo, you have to tell Expo to look at the rn-cli.config.js file. Edit the app.json config file at the project root and add the following under the expo key:

{
  "expo": {
       ...
       "packagerOpts": {
             "config": "./rn-cli.config.js"
        },
       ...
   }
}

Clear your cache after changing the settings: expo start --clear
Note: Expo v31.0.0 might need changes in rn-cli.config.js (check out breaking changes in https://blog.expo.io/expo-sdk-v31-0-0-is-now-available-cad6d0463f49)

While trying to use Web3 v1.0.0-beta 36 and truffle-hdwallet-provider, I also had to npm install url-parse and add the following code to global.js:

// see https://github.com/facebook/react-native/issues/16434
import URL from "url-parse";
global.URL = URL;
@elanpang

This comment has been minimized.

Copy link

elanpang commented Oct 6, 2018

It only works on React Native 0.56, I created a new project with React Native 0.57.1 (0.57.2 has other issue, don't care it), the issue ‘’web3.js cryptofromnode_modules/web3-eth-accounts/src/index.js`: Module does not exist in the module map‘’ happened again!

@theone3nu

This comment has been minimized.

Copy link

theone3nu commented Oct 7, 2018

It is working fine when running in expo. But when i ejected , ran npm install, react-native run ios. It is showing the error again. How can i get xcode file running.

@theone3nu

This comment has been minimized.

Copy link

theone3nu commented Oct 7, 2018

@dougbacela It is working fine when running in expo. But when i ejected , ran npm install, react-native run ios. It is showing the error again. How can i get xcode file running.

@jacksonng77

This comment has been minimized.

Copy link

jacksonng77 commented Nov 28, 2018

It only works on React Native 0.56, I created a new project with React Native 0.57.1 (0.57.2 has other issue, don't care it), the issue ‘’web3.js cryptofromnode_modules/web3-eth-accounts/src/index.js`: Module does not exist in the module map‘’ happened again!

Same problem for me. Has anyone solved this?

@jacksonng77

This comment has been minimized.

Copy link

jacksonng77 commented Dec 1, 2018

In order to make this work on Expo, you have to tell Expo to look at the rn-cli.config.js file. Edit the app.json config file at the project root and add the following under the expo key:

{
  "expo": {
       ...
       "packagerOpts": {
             "config": "./rn-cli.config.js"
        },
       ...
   }
}

Clear your cache after changing the settings: expo start --clear

While trying to use Web3 v1.0.0-beta 36 and truffle-hdwallet-provider, I also had to npm install whatwg-url and add the following code to global.js:

// see https://github.com/facebook/react-native/issues/16434
import { URL, URLSearchParams } from "whatwg-url";
global.URL = URL;
global.URLSearchParams = URLSearchParams;

I am on expo 31.0.4 and try to add rn-cli.config.js in app.json this way

"packagerOpts": {
  "config": "./rn-cli.config.js"
},

however it seems that my project still doesn't know what crypto is and I got this error

The package at "node_modules\web3-eth-accounts\src\index.js" attempted to import the Node standard library module "crypto". It failed because React Native does not include the Node standard library.

@sinchan

This comment has been minimized.

Copy link

sinchan commented Dec 4, 2018

@jacksonng77 checkout my updated comment. That error you're getting usually comes up because of not clearing the packager cache though. Make sure you're running expo with expo start --clear or expo start -c

@6pm

This comment has been minimized.

Copy link

6pm commented Dec 16, 2018

@dougbacelar It not works with ejected app(without expo). web3: 1.0.0-beta.37 and react-native 0.57.4. Did you tested with ejected app?

@anakornk

This comment has been minimized.

Copy link

anakornk commented Dec 20, 2018

Tried using node-libs-react-native instead as mentioned by @sinchan , got it to work on react-native 0.57.8 and web3 1.0.0-beta.37.
I need to manually add react-native-randombytes ,vm-browserify and some configuration files.
A Step by Step Guide that I went through and a boilertemplate can be found here.
https://github.com/anakornk/web3WithReactNative

@jacksonng77

This comment has been minimized.

Copy link

jacksonng77 commented Jan 1, 2019

@jacksonng77 checkout my updated comment. That error you're getting usually comes up because of not clearing the packager cache though. Make sure you're running expo with expo start --clear or expo start -c

Thank you! This works now, and I am able to view blocks, sign transactions and run contracts.

However, doing a web3.eth.accounts.create(web3.utils.randomHex(32)) gives me the following error:

Unhandled promise rejection: Error: No "crypto" object available. This Browser doesn't support generating secure random bytes.

It seems that the crypto library doesn't actually do anything although it is there.

@code-brewer

This comment has been minimized.

Copy link

code-brewer commented Jan 8, 2019

Hi, dougbacelar.

On step 9, you using :
const Web3 = require('web3');
Why not:
import {Web3} from 'web3'

Does it because web3.js don't support ES module style usage ?

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