Start a personal dev blog on your domain for free with Hashnode and grow your readership.
Get Started

Building custom Android modules for React Native

React Native applications have two sides (React's JavaScript side and the Android side). Assume these two sides are two sides of a river. Obviously, you need a bridge to cross this river. The React Native team built bridges for major things like Camera, Fingerprint, Scanner, etc... But they can’t cover every feature in Android. So, they gave us the tools to build our bridges.

I was using AsyncStorage to store the user preferences in my React Native app. But, the value stored by the AsyncStorage was not accessible from the Java layer of Android. So, I was starting my JavaScriptCore whenever my background service needed the user preferences. Then we decided to store the user preferences in Android’s Native Shared Preferences. I was searching for a corresponding bridge, on Google, and But, there was no bridge to store the Shared Preferences from the React Native's layer. I decided to create one.

To view the final repo, click here

Creating the first module

First, create an AndroidManifest.xml file with your package name.


We have to create the module by extending the ReactContextBaseModule. The first step is to override the name of the module.

public String getName(){
 return “SharedPreferences”;

I have already created a Java function to handle the data in Shared Preferences. Check the and to know how the Shared Preferences work inside the Java layer. Here, I have exposed three functions putSharedValue(key, value), getSharedValue(key) and clear(). These three functions can be accessed from our module.

We have to annotate the function with @ReactMethod for react methods.

public void setItem(String key, String value) {

I have initialised the SharedHandler with the application context provided by getReactApplicationContext(). Then I can call the function to execute the particular task.

In the previous ReactMethod, We didn’t have the requirement to send back anything to the JavaScript layer. When we want to get the value from Shared Preferences, we should send a callback. Sending a callback can be done as follows:

public void getItem(String key, Callback successCallback){
     String value = SharedDataProvider.getSharedValue(key);

If we need to send a callback, then we should send an extra parameter for SuccessCallback. The callback can be sent back to the JavaScript layer using the successCallback.invoke() function. If you also need an error callback, you can just add an extra parameter in the ReactMethod.

After creating the React Module, we have to register the module. If you don’t register the module, it can’t be accessed from the JavaScript layer. Shared Preferences module is ready. You can directly consume the API in your application, or you can publish it to NPM.

If you are publishing it to NPM, users have to make a few changes to build the Java files inside their Android app. For a detailed explanation of the setup process, you can check this file.

Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more

Matteo Mazzarolo's photo

Hey! Nice introduction tutorial! Do you have any suggestion on the implementation/bridging of an Android service in React-Native?
I'm asking because I'm considering all the available options for making react-native-beacons-android works even when the app is killed.
Thanks ;)

Show +1 replies
Matteo Mazzarolo's photo

Yep, I know, but what about making the service comunicate with React-Native?
Do you have any experience/example on this?
And thanks for the fast answer man!

Sriraman's photo

React Native won't be alive in background. Obviously, the Event listener which we created in the React Native layer will also be destroyed. Communication might not be possible. Some people said that it is possible to start the Javascript core from the background. But, I never tried it. I'll let you know if I find some workaround.

lee's photo

Thanks for this Sriraman, If I want to simply tweak an existing module e.g. react-native-maps to include map style capability, I need to import; in .java file that extends an Android MapView. However when running the app, it appears the MapStyleOptions is not in scope. Can you give me a clue, what are the steps to make this accessible in the Java? would i need to rebuild somehow from the original master? I don't see a reference to the other imports in this file elsewhere in the project for an example of how it was done.

Sriraman's photo

There are two ways to do it. You can create a new react native module and add the react-native-maps as the dependency.

Francisco Murillo's photo

Hi, I came here looking for an answer, I need to measure a custom component, but in react native you don't get the method .measure unless it's a native UI component as far as I understand from this:

The methods described here are available on most of the default components provided by React Native. Note, however, that they are not available on composite components that aren't directly backed by a native view. This will generally include most components that you define in your own app.


... my question is: Making a Bridged (as in this tutorial) component will make it get .measure method? I'd like to know before learning to do this so at least i won't have false expectations...

thank you!