DEV Community

Cover image for Share Code Between React Native and React.js
kpiteng
kpiteng

Posted on

Share Code Between React Native and React.js

Hello Developers! Many times we needs to reuse some code between React Native & React.js like state management code (Redux, Mobx, Apollo Client), utility & common functions, global constants, api call & common business logic. Today, we will learn to share code between React Native and React.js using Yarn Workspaces.

If you haven't checkout Yarn Workspaces I request you to check it first where I have explained SetUp Yarn Workspaces step-by-step.

Please download full source code from KPITENG GitHub.

Yarn Workspaces

Yarn Workspaces allow developers to create workspaces that share packages under the same workspace. Consider you have multiple packages and all are using common dependencies like graphql, axios, etc. To install dependency separately for each package (node_modules), Yarn Workspaces allow you to install packages at root level and you can access that dependency throughout all packages inside that workspaces. So with lots of installation, memory size will be reduced.

WML

Consider you have created a few common packages that you need to use for both React, React Native, Server (BackEnd), So whenever you change on common packages you need to add that updated package into your React, React Native node_modules. WML helps you to link your packages to where it is being used.

> wml add common /app/node_modules/@sharecode/common
Enter fullscreen mode Exit fullscreen mode

This command line will copy common packages inside the app's node_modules.

nohoist

As discussed earlier in Yarn Workspaces, whatever dependency (npm, node_modules) you were installing for your packages, it will be installed on your root node_modules instead of individual packages. If you checked then react-native packages refer to node_modules inside /app directory. But actually it will be installed on root (node_modules) so to link react-native dependency we are using nohoist which helps you to link your dependency. To do this you need to add few lines of code in your /app/package.json

"workspaces": {
   "nohoist": [
     "react-native",
     "react-native/**",
     "react",
     "react/**"
   ]
 }
Enter fullscreen mode Exit fullscreen mode

Steps by Step Integration

1) Create WorkSpace directory named - ReactShareCode

> mkdir react-share-code
> cd mkdir
Enter fullscreen mode Exit fullscreen mode

2) Create package.json file and add following lines of code, which contains a list of packages under WorkSpace

{
   "private": true,
   "name": "react-share-code",
   "version": "1.0.0",
   "workspaces":  [
      "app", "web", "common"
   ]
}
Enter fullscreen mode Exit fullscreen mode

Here, we have set up three packages (app, web, common) inside our Workspaces. We have app (React Native App), web (React.js Website), common (Common Code - Which used in React Native & React.js Website)

Now, let's create three projects, app (react native), web (react.js), common (common code between react & react native)

> npx react-native init app // this will create react native application
> npx create-react-app web // this will create react.js application

> mkdir common // this is our common directory for code share
> cd common

> yarn init -y // this will create package.json file with following code
Enter fullscreen mode Exit fullscreen mode
/common/package.json
{
   "name": "common",
   "version": "1.0.0",
   "description": "...",
   …
}
Enter fullscreen mode Exit fullscreen mode

Now, let's change some hierarchy of folder structure. Right now if you see,

> ls // it will print following
app web common package.json
Enter fullscreen mode Exit fullscreen mode

You see, everything are on root folder, let's move app, web, common inside packages folder

> mkdir packages

> mv app/ packages/app/
> mv web/ packages/app/
> mv common/ packages/app/
Enter fullscreen mode Exit fullscreen mode

You can directory drag your app, web, common folder directory to the packages folder. We have changed folder hierarchy, so we need to update root package.json according

Update react-share-code/package.json file look like this

{
   "private": true,
   "name": "react-share-code",
   "version": "1.0.0",
   "workspaces":  [
      "packages/*"
   ]
}
Enter fullscreen mode Exit fullscreen mode

Till, all going well, If you see packages name it will be like “name”: “app”, “name”: “web”, “name”: “common”, but as per best coding practices we need to append project name, workspace name. So, lets change packages name

react-share-code/packages/app/package.json -

{
   - "name": "app",
   + "name": "@sharecode/app"
} 
Enter fullscreen mode Exit fullscreen mode

react-share-code/packages/web/package.json -

{
   - "name": "web",
   + "name": "@sharecode/web"
}  
Enter fullscreen mode Exit fullscreen mode

react-share-code/packages/common/package.json -

{
   - "name": "common",
   + "name": "@sharecode/common"
}
Enter fullscreen mode Exit fullscreen mode

So, we have finish with

  • WorkSpace Creation
  • Project Creation (React Native, React.JS)
  • Common Folder Creation
  • Structure Folder Hierarchy Into packages directory
  • Updated packages name

Now, let's put some reusable code into a common directory.

Create file index.js inside common directory and add following line -

export const sharedVariable = “Shared Variable”;
Enter fullscreen mode Exit fullscreen mode

Now, let's use this in React Native Project, to use code we need to add it as a dependency, So lets update /packages/app/package.json file

{
   "devDependencies": {
    + "@sharecode/common": "1.0.0"
   },
   + "workspaces": {
      + "nohoist": [
         + "react-native",
         + "react-native/**",
         + "react",
         + "react/**"
      + ]
   + }
}
Enter fullscreen mode Exit fullscreen mode

Here, we have added @sharecode/common as a devDependency and added workspaces - nohoist to get reference of react-native.

Now, lets go to code /app/app.js

+ import {sharedVariable} from “@sharecode/common”;

return (
   + <Text>{sharedVariable}</Text>
)
Enter fullscreen mode Exit fullscreen mode

Before start running project, let’s remove node_modules both /app and root /node_modules to reinstall packages

app > rm -rf node_modules ../../node_modules
app > yarn install // install node_modules 

Enter fullscreen mode Exit fullscreen mode

Now, let's run the react-native app, you will see Text Value “Shared Variable” which is fetched from common logic.

Same way, lets integrate it into React.js Application.

/web/index.js
+ import {sharedVariable} from “@sharecode/common”;

return (
   + <div>{sharedVariable}</div>
)
Enter fullscreen mode Exit fullscreen mode

Run the react.js application you will get printed “Shared Variable”

That’s it, you have used the same code between React Native & React.JS.

What kind of code you can add into shared/common -

  • Redux/Redux Saga/Redux Rematch/Apollo Client/Mobx
  • Common API Imports
  • Common Themes/ Fonts Settings
  • Common Variables/ Constants
  • Common API Calls

You can add as much code as you require as per project needs.

Now, If you have changed anything in your common folder/ code, then to merge your latest common packages we are using WML.

app > wml ../common ./node_modules/@reactsharecode/common 
Enter fullscreen mode Exit fullscreen mode

Above command will copy code files of common into app/web node_modules under @reactsharecode/common packages.

To start linking you can do

app > wml start
Enter fullscreen mode Exit fullscreen mode

Execute above WML commands whenever you have updated anything into your common packages, WML will merge code into app/node_modules/@reactsharecode/common and web/node_modules/@reactsharecode/common.

Please download full source code from KPITENG GitHub.

Thanks for reading Blog!

KPITENG | DIGITAL TRANSFORMATION
www.kpiteng.com/blogs | hello@kpiteng.com
Connect | Follow Us On - Linkedin | Facebook | Instagram

Top comments (6)

Collapse
 
jonisar profile image
JoniSar

Nice article thanks, you might also want to take a look at this (using composable components to share logic, hooks, props, types and even design tokens):

bit.cloud/blog/creating-a-cross-pl...

Collapse
 
kathirpandian1993 profile image
kathirpandian1993

is there a way to reuse the reactjs code in react-native or react-native code in reactjs

Collapse
 
kpiteng profile image
kpiteng

We can use only JS Code which are not dependent on any of either React Native/ React.js library. Example - If you want to share code which uses React Native Async Storage then that will create issue in React.js - as React.js don't have that library. But yes whatever common code / pure JS code we can share across both apps.

Collapse
 
aliakbarazizi profile image
Ali Akbar Azizi • Edited

You can't share UI elements, but you can create custom hook and share that logic between component

Collapse
 
kmsayem12 profile image
Saifullah SaYem

I think you can share react native UI components for web, But you need to use react-native-web package.
example here necolas.github.io/react-native-web/

Collapse
 
francoism profile image
François Michaud

Nice article. I notify a little error at step 1 :

mkdir react-share-code
cd mkdir
Enter fullscreen mode Exit fullscreen mode

:-)