Develop your own react-native component and publish it to npm

Keywords: React npm Android github

Write before

When doing react-native development, we often find some third-party components that are easy to install and use by npm install.Have you ever thought about how we should develop and publish a component ourselves while using it?Whether it's sharing multiple projects for yourself or using open source for others, it's cool.

So today, I'm going to talk about how to develop a component of my own, open source to github, and publish to npm, using an example of a CardView component I've developed for use with ios and android.

A description

My component name is react-native-rn-cardview .If the react-native-cardview component name appears in the tutorial, it means the same thing.

1 Create and implement

1.1 Create a custom component template project

1.1.1 Installation react-native-create-library

$ npm install -g react-native-create-library

1.1.2 Create Template Project

We use the command react-native-create-library to create the project, specify the platform as ios,android, specify the package in android, other parameters can refer to themselves in react-native-create-library Documentation on github, not to mention here

$ react-native-create-library --package-identifier com.quenice.cardview --platforms android,ios cardview

Let's rename the project name

$ mv cardview react-native-cardview

It may be said that the owner of the building did not directly generate the react-native-cardview project, but instead asked the owner to generate the cardview and rename it.This is a trick, because some component-related names or classes are prefixed with react-native or RN by default for projects produced with react-native-create-library.
For example, if your initial project name is react-native-card-view, the component name defined in package.json will be react-native-react-native-card-view, and the related class defined in the android module will be, which is obviously ugly.

ok, let's continue.

Now the directory structure:

$ tree
└── react-native-cardview
    ├── android
    │   ├── build.gradle
    │   └── src
    │       └── main
    │           ├── AndroidManifest.xml
    │           └── java
    │               └── com
    │                   └── reactlibrary
    │                       ├──
    │                       └──
    ├── index.js
    ├── ios
    │   ├── RNCardview.h
    │   ├── RNCardview.m
    │   ├── RNCardview.podspec
    │   ├── RNCardview.xcodeproj
    │   │   └── project.pbxproj
    │   └── RNCardview.xcworkspace
    │       └── contents.xcworkspacedata
    └── package.json

Once you've built your component project, you're ready to write your implementation code

2 Write code

Writing code is divided into three parts, one part is android native code, one part is iOS native code, and one part is react-native (or javascript) code.Because react-native-cardview Only native android modules are involved, so this article does not cover iOS native module development at this time. If you are interested, I can start a separate article to focus on native iOS modules.

2.1 Writing Android Native Module

There are generally three classes required to write native android code:

2.1.1 RNxxxModule

The main purpose of this class is to define the native module name, which can be accessed directly in javascript through, where XXX is the return value of the getName method defined in the RNxxxModule class.Below are my components react-native-cardview Module class in

package com.quenice.reactnative;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;

public class RNCardViewModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;

  public RNCardViewModule(ReactApplicationContext reactContext) {
    this.reactContext = reactContext;

  public String getName() {
    return "RNCardView";

2.1.2 RNxxxManager

Manager classes are primarily native implementations of components and map react-native component properties to native properties

package com.quenice.reactnative;

import android.view.View;

import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;

public class RNCardViewManager extends ViewGroupManager<CardView> {
    public String getName() {
        return "RNCardView";

    protected CardView createViewInstance(ThemedReactContext reactContext) {
        CardView cardView = new CardView(reactContext);
        cardView.setContentPadding(0, 0, 0, 0);
        ReactViewGroup reactViewGroup = new ReactViewGroup(reactContext);
        return cardView;

    @ReactProp(name = "cardElevation", defaultFloat = 0f)
    public void setCardElevation(CardView view, float cardElevation) {

2.1.3 RNxxxPackage

The Package class is primarily used to register native modules, native component implementations, that is, to register the Module and Manager classes above

package com.quenice.reactnative;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;
public class RNCardViewPackage implements ReactPackage {
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
      return Arrays.<NativeModule>asList(new RNCardViewModule(reactContext));

    // Deprecated from RN 0.47
    public List<Class<? extends JavaScriptModule>> createJSModules() {
      return Collections.emptyList();

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
      return Arrays.<ViewManager>asList(new RNCardViewManager());

2.2 Write native iOS code

iOS can be implemented directly by using shadow-related attributes in react-native, so this article does not cover

2.3 Write ReactNative code

Once you've written the native android/iOS module, you need to write javascript code to bridge react-native with the native module.

import PropTypes from 'prop-types';
import {requireNativeComponent, View} from 'react-native';

const iface = {
    name: 'CardView',
    propTypes: {
        cardElevation: PropTypes.number,
        maxCardElevation: PropTypes.number,
        backgroundColor: PropTypes.string,
        radius: PropTypes.number,
        ...View.propTypes, // include the default view properties

module.exports = requireNativeComponent('RNCardView', iface);

3 Code upload and component Publishing

3.1 Code uploaded to github

After writing the code, we need to upload it to github, and then we need to use the GitHub address of the code when the component is published to npm
.If you haven't done a github-related configuration, you can refer to another article from me: Install GIt and configure connection GitHub

Execute the following command to synchronize the code into your github repository:

$ git add .
$ git commit -a -m "initial commit"
$ git push -u origin master

After synchronization, you can go to github to see if push succeeds:

3.2 Component Publishing

After you have developed your components, if you want to install them in another project (or for others to install and use), then your components must be published to the npm registry.

3.2.1 npm registry

What is npm registry

Simply put, npm registry is equivalent to a package registration administration center.It manages the various plug-ins released by developers around the world, and developers can install the required plug-ins via npm install.

The official npm registry is:

The domestic speed is faster:


You can view the currently used registry:

$ npm config get registry


Of course, you can also switch the npm registry currently in use by command

# Global Switching
$ npm config set registry

Sometimes you just want to switch temporarily while executing some npm commands. At this time, you can use --registry to specify the registry for the temporary switch, such as when publishing in npm

$ npm publish --registry

You can temporarily specify that, of course, the registry will still be restored to its original registry after the command execution ends

3.2.2 Create/login npm registry account

To publish components to npm registry, you must be a registered user of npm registry by:

$ npm adduser

To add a new user, or you are already Official Web Register a user by:

$ npm login

To log in to the npm registry account.

Use the following two ways to confirm that you have successfully created/logged on to the npm registry

  1. Command $npm whoami confirms successful local logon authentication
  2. Open Online Check to see if account creation was successful

3.2.3 Preparing for Release and.npmignore

  1. Define which files are not uploaded to github in.gitignore
  2. Define which files are not packaged when published in.npmignore
  3. If you have.gitignore but no.npmignore file, then.gitignore can act as.npmignore
  4. Specific rules can be referred to as: npm-developers, .gitignore or .npmignore pattern rules package.json

The package.json file defines all the information published, including key information such as component name, version, author, description, dependency, and so on.Specific can be referred to Working with package.json

Here are react-native-cardview The package.json file contents of:

  "name": "react-native-rn-cardview",
  "version": "1.0.0",
  "description": "A ReactNative CardView Component for android and iOS",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "keywords": [
  "author": {
    "name": "quenice",
    "email": ""
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": ""
  "devDependencies": {
    "react": "^16.2.0",
    "react-native": "^0.53.0"
  "peerDependencies": {
    "react": "^16.2.0"
  "dependencies": {
    "prop-types": "^15.6.0"
} Writing

The file can be used to specify how components are used, considerations, and so on.Write in Markdown syntax

3.2.4 Release

Once you're ready, you can publish.It is important to note that the first release is different from the subsequent update release.

First Release

For the first time, execute the command directly:

$ npm publish

That's it. You can check online to see if the publication was successful.Access the link (<package>is the npm package name you published):<package>
See if there's already content, there's a description that the publication was successful.

Update Publication

If it's not your first release, you need to execute two commands

$ npm version <update_type>
$ npm publish

The $npm version command is used to automatically update the version number with the value patch ``minor `major'for update_type.So in what scenarios should you choose what update_type?Look at the table below

update_type scene Version Number Rule Give an example
- First Release Version number 1.0.0 1.0.0
path When fixing bug s, minor changes Incremental change from version number 3 1.0.0 -> 1.0.1
minor When new functionality comes online and does not affect existing functional modules in the current version Incremental change from version number 2 1.0.3 -> 1.1.3
major When several new functional modules are online and have an impact on existing functionality in the current version Incremental change from version number 1 1.0.3 -> 2.0.0

Be careful

If the first release number is not 1.0.0, use $NPM version <update_type>
To update will cause errors, because you did not follow the version rules it stipulated. At this time, you can manually modify the version field in package.json to match the version number of the contract rules, then execute $npm publish directly, and the next incremental update will automatically update the version number using $NPM version <update_type>

4 Tests

Components need to be tested from development to final release to ensure proper functionality. How do you test them?

4.1 Create a react-native project

First we create a react-native project called example

$ react-native init example

The example project directory can be at the same level as the component project directory react-native-cardview, and of course you can put it anywhere you want. For ease of operation, we'll put both directories at the same level.That is, the directory is now like this

$ tree
├── example
└── react-native-cardview

Then all we have to do is install the local or published components into the example project for testing

4.2 Local Code Testing

Before the components are released, we can install the local code directly into the example project and test it in several ways

4.2.1 yarn link

$ cd react-native-cardview
$ yarn link
$ cd ../example
$ yarn link react-native-cardview
$ react-native link react-native-cardview

Explain a few points:

  1. yarn link is a local component that registers the local code in the current directory as react-native-cardview with yarn. The component name react-native-cardview is actually based on the value of the name field in package.json, regardless of the directory name, except that it exactly equals the directory name here
  2. The yarn link react-native-cardview command installs the local component react-native-cardview into the example project, which you can find in example/node_modules
  3. react-native link react-native-cardview, as you should know, is a native module link for android/iOS
  4. In fact, yarn link simply means making a symbol link, that is, the content in the example/node_modules/react-native-cardview/directory points to react-native-cardview/directory content, and you change the code in the react-native-cardview/directory, which is equivalent to directly changing the code in the example/node_modules/react-native-cardview/directory.Can achieve the purpose of modifying component code while looking at the effect

Configuring local paths in 4.2.2 package.json

Add dependencies directly to example's package.json


  "dependencies": {
    "react-native": "^0.55.4",

Then execute

$ react-native link react-native-cardview

Like yarn link, it is equivalent to making a symbol link, directly modifying the code in the react-native-cardview/directory, and directly changing the code in the example/node_modules/react-native-cardview/directory

4.2.3 Direct copy local code

This is a straightforward way to copy react-native-cardview/directory directly to example/node_modules/react-native-cardview/directory

$ cp -rf react-native-cardview/ example/node_modules/

Then execute

$ react-native link react-native-cardview

The disadvantage of this approach is that you need to manually copy to example/node_modules/react-native-cardview/each time you change the code

4.3 Uploaded/released code tests

Components that have been uploaded to github or published to npm registry are tested in the same way that we normally install a third-party component.

4.3.1 via github

Add your code and upload it to the github repository via git, so you can install your components directly via npm install

npm install --save


npm install --save

Note: Replace the above HTTPS or SSH with the URL on your own ghthub

Then execute

$ react-native link react-native-rn-cardview

4.3.2 via npm

This is no different from following third-party components

$ npm install --save react-native-rn-cardview

Then execute

$ react-native link react-native-rn-cardview


At this point, the full development-test-release lifecycle of a react-native component is complete.

Because it's a component I developed in conjunction with myself react-native-rn-cardview The actual development process, so there are inevitable omissions, there are certainly many deficiencies.If you have any problems or find errors, you are welcome to leave a message in the comments area for us to discuss and solve together.

In addition, if you need to use CardView in react-native, you are welcome to use it react-native-rn-cardview


Author: Quenice
Source: Short Book
The copyright in the brief book is owned by the author. For any form of reprinting, contact the author for authorization and indicate the source.

Posted by littleelmo on Tue, 07 May 2019 17:10:40 -0700