DEV Community

Cover image for Step-by-Step Guide to Creating an Expo Monorepo with Nx
Emily Xiong for Nx

Posted on • Originally published at blog.nrwl.io

Step-by-Step Guide to Creating an Expo Monorepo with Nx

This blog will show you how to create an Expo monorepo with Nx. In this example, you will be creating two Expo apps in a monorepo with @nx/expo: one shows random facts about cats, and the other shows random facts about dogs.

Cats App Screenshot

Dogs App Screenshot

As shown in the above screenshots, these two apps have the same branding and reuse all components.

This blog will go through:

  • How to create a monorepo workspace with Nx
  • How to share a React Native library
  • How to build an Expo app
  • How to submit an Expo app to the app store

Github repo: https://github.com/xiongemi/nx-expo-monorepo


Creating an Nx Workspace

To create a new Nx workspace, run the command npx create-nx-workspace in the terminal. In this example, let’s name it nx-expo-monorepo:

✔ Where would you like to create your workspace? · create-nx-monorepo
✔ Which stack do you want to use? · react
✔ What framework would you like to use? · expo
✔ Application name · cats
✔ Enable distributed caching to make your CI faster · No
Enter fullscreen mode Exit fullscreen mode

This will create an integrated repo. What is an integrated repo?

An integrated repo contains projects that depend on each other through standard import statements. There is typically a single version of every dependency defined at the root.
https://nx.dev/concepts/integrated-vs-package-based#integrated-repos

Now, your Nx workspace should have cats and cats-e2e under the apps folder and an empty libs folder:

Nx workspace with cats app

Existing Nx Workspace

If you already have an Nx workspace, you need to install the @nx/expo package:

npx nx add @nx/expo
Enter fullscreen mode Exit fullscreen mode

To create an Expo app, run:

npx nx generate @nx/expo:app cats
Enter fullscreen mode Exit fullscreen mode

Alternatively, if you use Visual Studio Code as your code editor, you can also create apps using Nx Console:

nx console

Install Tech Stacks

Here are the tech stacks this example is going to use:

# npm  
npm install react-native-paper react-native-safe-area-context --save  

# yarn  
yarn add react-native-paper react-native-safe-area-context  

# pnpm  
pnpm add react-native-paper react-native-safe-area-context --save
Enter fullscreen mode Exit fullscreen mode
# npm  
npm install react-native-paper react-native-screens @react-navigation/native-stack --save  

# yarn  
yarn add react-native-paper react-native-screens @react-navigation/native-stack  

# pnpm  
pnpm add react-native-paper react-native-screens @react-navigation/native-stack --save
Enter fullscreen mode Exit fullscreen mode

Create a Shareable UI Library

With all the required libraries installed, you need to create a sharable UI library:

npx nx generate @nx/expo:lib ui
Enter fullscreen mode Exit fullscreen mode

Now under the libs folder, a ui folder has been created:

ui folder

To create a component in the ui library, run:

npx nx generate @nx/expo:component carousel --project=ui --export
Enter fullscreen mode Exit fullscreen mode

You can see that a carousel folder has been created in the libs/ui/src/lib folder:

carousel folder

Next, modify this component to display the content with props passed in:

Now you can use this component in your app directly using an import:

import { Carousel } from '@nx-expo-monorepo/ui';
Enter fullscreen mode Exit fullscreen mode

Add Navigation

This project is going to use the stack navigator from @react-navigation/native. So the app needs to import from @react-navigation/stack. In apps/cats/src/app/App.tsx, you can change the UI to have one screen displaying a carousel with mock data:

Run the app with nx start cats, and you should be able to see the app on the simulator:

Page on the simulator (left: iOS, right: Android)

Cats app screenshot

Add Another App

In this example, there is already a Cats app. To create the Dogs app, run the command:

npx nx generate @nx/expo:app dogs
Enter fullscreen mode Exit fullscreen mode

Alternatively, if you use Visual Studio Code as your code editor, you can also create apps using Nx Console:

nx console

Under the apps folder, there should be cats/, dogs/ and their e2es.

apps folder

You can reuse the UI library in the Dogs app in apps/dogs/src/app/App.tsx with the below code:

Build Expo Apps

EAS Build is a hosted service for building app binaries for your Expo and React Native projects. To set up EAS locally:

1. Install EAS CLI

EAS CLI is the command-line app to interact with EAS services in the terminal. To install it, run the command:

npm install -g eas-cli
Enter fullscreen mode Exit fullscreen mode

2. Login To EAS

If you are not logged in, run the command:

eas login
Enter fullscreen mode Exit fullscreen mode

3. Build the Apps

After the EAS setup, you can build apps by running the command:

npx nx build cats  
npx nx build dogs
Enter fullscreen mode Exit fullscreen mode

There are different options you can specify with the build command. For example, you can specify the platform you want to build:

npx nx build cats --platform=all  
npx nx build cats --platform=android  
npx nx build cats --platform=ios
Enter fullscreen mode Exit fullscreen mode

Alternatively, if you want to create a build to run on a simulator/emulator, you can run:

npx nx build cats --profile=preview
Enter fullscreen mode Exit fullscreen mode

You can view your build status at https://expo.dev/:

expo.dev

If you want to create a build locally using your own infrastructure:

npx nx build cats --local
Enter fullscreen mode Exit fullscreen mode

Here is the complete list of flags for the build command: https://nx.dev/packages/expo/executors/build.

Submit to the App Store

Before you submit, you need to have paid developer accounts for iOS and Android.

1. Run the production build

To submit to the app store, you can build the app by running:

npx nx build cats --profile=production
Enter fullscreen mode Exit fullscreen mode

2. Submit the Build

You can manually upload the build bundle binary to the app store, or you can submit it through EAS.

First, in app.json under the project apps/cats/app.json, you need to make sureios.bundleIdentifier and android.package keys are correct:

app.json

To submit your app to the app stores, run:

npx nx submit cats
Enter fullscreen mode Exit fullscreen mode

Nx will prompt you to choose the platform to which you want to submit:

submit prompt

Or you can also specify the platform directly in the initial command:

npx nx submit cats --platform=all  
npx nx submit cats --platform=android  
npx nx submit cats --platform=ios
Enter fullscreen mode Exit fullscreen mode

It will then ask you to choose which binary to submit from one of the following options:

  • The latest finished Android build for the project on EAS servers.
  • Specific build ID. It can be found on the builds dashboard.
  • Path to an .apk or .aab or .ipa archive on your local filesystem.
  • URL to the app archive.

Alternatively, you can submit your app on the expo.dev site. Go to your build, under options, choose “Submit to an app store”:

submit to an app store

Summary

In this article, you have learned how to:

  • Create multiple apps in a monorepo using @nx/expo
  • Create a shared library
  • Build your app using EAS
  • Submit your app to the App Store

With Nx, it is easy to create and scale up an Expo app. Even though this app is currently a simple 2-page app, you can easily scale it up with more libraries and components. Furthermore, you can also reuse those libraries in the future if you decide to add another app to the repo.

Learn more

Top comments (1)

Collapse
 
vendramini profile image
André Vendramini

Hey! Nice article :) it has helped a lot!

However, either following the step-by-step or cloning your repository gives the same error. I'm trying to compile locally with: nx build cats --local --profile=preview --platform=ios and I get:

[READ_APP_CONFIG]
PluginError: Failed to resolve plugin for module "@config-plugins/detox" relative to "/var/folders/bm/z5qdvvh94_q565bkp7kty3zm0000gn/T/eas-build-local-nodejs/fd2cea83-5a69-47f9-9f27-ad1288cd6861/build/apps/cats"
    at resolvePluginForModule (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/utils/plugin-resolver.js:72:11)
    at resolveConfigPluginFunctionWithInfo (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/utils/plugin-resolver.js:152:7)
    at resolveConfigPluginFunction (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/utils/plugin-resolver.js:143:7)
    at withStaticPlugin (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/plugins/withStaticPlugin.js:87:70)
    at /Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/plugins/withPlugins.js:30:84
    at Array.reduce (<anonymous>)
    at withPlugins (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config-plugins/build/plugins/withPlugins.js:30:18)
    at withConfigPlugins (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config/build/plugins/withConfigPlugins.js:36:47)
    at fillAndReturnConfig (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config/build/Config.js:218:78)
    at getConfig (/Users/vendramini/.npm/_npx/7cb2e17578656054/node_modules/@expo/config/build/Config.js:274:10)

Build failed
Unknown error. See logs of the Read app config build phase for more information.
npx exited with non-zero code: 1
Enter fullscreen mode Exit fullscreen mode

Any idea? Thank you :)