How did I publish my first React Native library to npm?
Tags: react, reactnative, typescript, npm
Published: 2020-12-04 16:44:07

Hi, everyone 👋 I'm Fatih. I'm a front end developer from Turkey and this is my first post about my first react native library that I published to npm 2 days ago.

First of all, if you wanna take a look at it: 
[NPM](https://www.npmjs.com/package/@digieggs/rn-country-code-picker)
[GitHub Repo](https://github.com/DIGIEGGS/rn-country-code-picker)

It's a dropdown component that let's you pick a country dial-in code for your phone number input.

So, it's been 5 months since I started to work as a professional front end developer. I mainly work with React but I am relatively new in React Native development. I was working on OTP login with firebase and I built a phone number input. Everything was okay but something was missing, a country code picker. So I checked the dropdown/picker packages but since they were not customizable and and I had my own design on my mind, I decided to build my own. At the end, I built a nice, searchable country code picker with flags and everything and my boss liked it a lot and suggested that I should publish it to NPM.

It was a process that I've made some research to get it done and learned many things about creating a package and publishing it. So, I decided to share this steps with the community.

# Initializing the project

Initialize a React Native bare workflow project with TypeScript:

`npx react-native init AwesomeTSProject --template react-native-template-typescript`

# Dependencies and package.json configuration

The most important thing is to get the package.json right. It contains all the necessary information about your soon-to-be package. Now, don't copy paste the info below, take a look at your package.json and edit/add fields accordingly:

```
{
  "name": "@digieggs-rn-country-code-picker", // Your package's name
  "version": "1.0.0", // Keep it 1.0.0 for now. It will increase automatically when you patch the project
  "main": "lib/module/index.js", // Entry point of the package
  "module": "lib/module/index.js", // Entry point of the package
  "react-native": "src/index.ts", // Entry point of the project
  "types": "lib/typescript/index.d.ts", // Entry point of the type definitions
  "description": "A searchable dropdown component to select a country code for your phone number input.", // Description to show on npmjs.com
  "files": [
    "lib/",
    "src/"
  ], // Entry point of the necessary files
  "keywords": [
    "react-native",
    "country",
    "country-code",
    "dialing code",
    "picker",
    "mobile",
    "ios",
    "android"
  ], // Some keywords to make the package easier to be found
  "bugs": {
    "url": "https://github.com/DIGIEGGS/rn-country-code-picker/issues"
  },
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "prepare": "bob build" // The command to build our package's core
  },
  "dependencies": {
    "react": "16.13.1",
    "react-native": "0.63.3",
    "react-native-svg": "^12.1.0"
  },
  "devDependencies": {
    ...
    "@react-native-community/bob": "^0.16.2", // The builder. I'll talk about it
  },
  "peerDependencies": { // Add the dependencies that you want the user to install manually here. In my case it react-native-svg for the icons in the component
    "react-native-svg": "^12.1.0"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/DIGIEGGS/rn-country-code-picker"
  }, // repository info to show on npmjs.com
  "author": "Fatih Can <contact@fatihcan.dev>", // author info to show on npmjs.com
  "license": "MIT", // license info,
  "@react-native-community/bob": {
    "source": "src",
    "output": "lib",
    "targets": [
      "module",
      "typescript"
    ]
  } // Config for the builder bob
}

```

After you are done with the package.json, let's install our dependencies with yarn or npm:

`yarn` or `npm install`

The most important dependency here is:
{% github callstack/react-native-builder-bob no-readme %}

This library will compile the ts files to js files and build type definitions of our components into a `lib` folder.

# TypeScript configuration

After that, let's get to the tsconfig.json. You can copy/paste it if you like:

```
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "jsx": "react-native",
    "lib": ["dom", "esnext"],
    "moduleResolution": "node",
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "strict": true
  },
  "include": ["src/index.ts"],
  "exclude": ["node_modules", "babel.config.js", "metro.config.js", "jest.config.js"]
}
```

# Source folder and necessary files

After that, let's create a src folder. This folder will contain the source of our package:

![src](https://dev-to-uploads.s3.amazonaws.com/i/pfzw8mhzyhrb28m5l0de.jpg)
 
After that, create an index.ts file and export the main component like this:

```
export { default as CallingCodePicker } from './CallingCodePicker';
```

It's almost done. Let's create the necessary ignore files and we will build our package.

.gitignore
```
...

# generated files by bob
lib/

```

.eslintignore
```
node_modules/

# generated files by bob
lib/
```

.npmignore
```
tsconfig.json
src

# Logs
*.log
npm-debug.log

# Dependency directory
node_modules

# Runtime data
tmp
```

# Building the library

Now, let's run the following command to build our package with bob:

`yarn run prepare`

If you see the following logs, it means our package is ready to test:

![bob](https://dev-to-uploads.s3.amazonaws.com/i/e097ojuqyt3v1srqkl9n.jpg)

# Testing

Run the following command:

`npm pack`

builder-bob will compress our project into a .tgz file that allows us to install it with yarn/npm into another project to see if it being installed successfully.

Now, you should see a .tgz file in the structure. Move it to Desktop and initialize another React Native project. I know... 🥱 Bear with me 👊

After that project is initialized, change the following path with the path of your .tgz file and run:

`npm install C:\Users\digieggs\Desktop\digieggs-rn-country-code-picker-1.0.4.tgz`
or
`yarn add C:\Users\digieggs\Desktop\digieggs-rn-country-code-picker-1.0.4.tgz`

After a successfull installation, you can import the component like this:

`import { CallingCodePicker } from '@digieggs/rn-country-code-picker'`

# GitHub configuration

We need a GitHub repo if you wish to share the code with everyone and maintain the project. Run the following commands with appropriate names:

```
git init
git add .
git commit -m “Initial commit”
git remote add origin https://github.com/<username>/<package_name>.git
git push -u origin master
```

Don't forget to edit the `repository` and `bugs` section in package.json.

# Publishing to NPM

After that, we are ready to publish our package. Run the following command to define a user. It will ask you your username, password and email.

`npm adduser`

Make sure to confirm you email address before running the publish command:

`npm publish`

And congrats! 🥳 The package is live and ready to be installed from anywhere with the following commands:

`npm install <package_name>`
or
`yarn add <package_name>`

# Conclusion 
You've just built your first npm package. Publishing a package may seem hard but it's not. I hope it was a clear guide, it's my first tutorial blog post. Please feel free to ask questions if you got stuck anywhere.