# Deploying a Monorepo Using Yarn Workspaces to Vercel

**Author:** Ismael Rumzan

---

Migrating from one framework to another can sometimes be a laborious experience, especially if you have a chunk of functionality that needs to be used in both applications during the migration process.

With a large codebase it may take a while to complete an incremental migration. Monorepos allow you to move portions of your application piece-by-piece, and continue to deploy the application under one domain and from a single code repository.

In this guide you will deploy a monorepo using Yarn workspaces and the following components:

- A `create-react-app` application
  
- A Next.js application
  
- A common library containing a utility function shared between each application
  

## Structure

Before diving in, let's look at the monorepo structure we will create:

`apps/ frontend/ nextapp/ packages/ site-info/`

Each of the 2 folders in `apps` will be Yarn [workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) and any folder in the `packages` folder will also be a workspace. Each workspace will have its own `package.json` file with dependencies and everything will be installed and linked in the root `node_modules` when the `yarn` command is run. For the purpose of this guide, the term **workspace** will be used to describe each of these folders.

## Process

1. [Set up the monorepo root with Yarn](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#set-up-the-monorepo-root-with-yarn)
   
2. [Create a workspace for a Create React App application](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#create-a-workspace-for-a-create-react-app-application)
   
3. [Create a workspace for a Next.js application](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#create-a-workspace-for-a-next.js-application)
   
4. [Create a shared library workspace with a utility function](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#create-a-shared-library-workspace-with-a-utility-function)
   
5. [Use the function inside both applications](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#use-the-function-inside-both-applications)
   
6. [Connect all the pieces with Yarn workspaces](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#connect-all-the-pieces-with-yarn-workspaces)
   
7. [Test the monorepo locally](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#test-the-monorepo-locally)
   
8. [Deploy to Vercel](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#deploy-to-vercel)
   
9. [Configure the Ignored Build Step on Vercel](https://vercel.com/guides/deploying-yarn-monorepos-to-vercel#configure-the-ignored-build-step-on-vercel)
   

## Create a monorepo using Yarn workspaces

### Set up the monorepo root with Yarn

Create your monorepo folder from the command line and initialize it.

`mkdir yarn-monorepo cd yarn-monorepo yarn init`

Choose all the default values for each prompt, except for `private` which you should mark as `true`. The default is `false` and Yarn workspaces only work with private projects. This will create a `package.json` file that looks like this:

`{ "name": "yarn-monorepo", "version": "1.0.0", "main": "index.js", "license": "MIT", "private": true }`

### Create a workspace for a Create React App application

Create the `apps` folder to contain the workspaces for all applications.

`mkdir apps cd apps`

Create the `frontend` workspace by running the following command inside `yarn-monorepo/apps`:

`yarn create react-app frontend`

This creates a `create-react-app` application inside the `frontend` folder.

### Create a workspace for a Next.js application

From the folder, `yarn-monorepo/apps`, run:

`yarn create next-app nextapp`

This creates a Next.js application inside the `nextapp` folder.

### Create a shared library workspace with a utility function

Create a new `packages` directory for code that will be shared within the monorepo. After that, create a new `site-info` folder in the `packages` directory and initialize it with `yarn`. You can create any number of packages here to share code amongst multiple applications.

`mkdir packages cd packages mkdir site-info cd site-info yarn init`

> \*\*Note: \*\*You can use the default values for the answers to all prompts.

You will now create a function that you can use in both the `create-react-app` and the Next.js applications. This function will output the site title and subtitle.

Create an `index.js` file inside `yarn-monorepo/packages/site-info` with the following content:

`const PROJECT = { title: 'Site Title', subtitle: 'My great monorepo', }; export function getSiteInfo() { return { title: PROJECT.title, subtitle: PROJECT.subtitle }; }`

### Use the function inside both applications

Replace the content of `yarn-monorepo/apps/nextapp/pages/index.js` with:

`import Head from 'next/head'; import styles from '../styles/Home.module.css'; // Import the shared function into the Next.js application import { getSiteInfo } from 'site-info'; export default function Home() { let siteInfo = getSiteInfo(); //Define a variable to get the values return ( <div className={styles.container}> <Head> <title>{siteInfo.title}</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> {/*Output the site title and subtitle to the screen*/} <main className={styles.main}> <h1 className={styles.title}>Welcome to {siteInfo.title}</h1> <p className={styles.description}>{siteInfo.subtitle}</p> </main> </div> ); }`

Replace the content of the `yarn-monorepo/apps/frontend/src/App.js` file with:

``import './App.css'; // Import the shared function into the `create-react-app` application import { getSiteInfo } from 'site-info'; export default function App() { //Define a variable to get the values let siteInfo = getSiteInfo(); return ( <div className="App"> {/*Output the site title and subtitle to the screen*/} <header className="App-header"> <h1>{siteInfo.title}</h1> <p>{siteInfo.subtitle}</p> </header> </div> ); }``

### Connect all the pieces with Yarn workspaces

Add the following to the `package.json` file in the root of `yarn-monorepo`to tell Yarn about your workspaces:

`"workspaces": ["apps/*", "packages/*" ]` > This configures 3 workspaces in your project. Each workspace is first located by path, but addressed by the `name` value in their respective `package.json` files. In this example, the project has the following workspaces: - apps/frontend: A `create-react-app` application    - apps/nextapp: A Next.js application to which the frontend application is being migrated    - packages: A folder containing reusable packages for sharing code between the applications    From the repository root directory, `yarn-monorepo`, run the following in order to install and connect all packages: `yarn` ### Test the monorepo locally Add the following content to the `package.json` file at the root of `yarn-monorepo`: `"scripts": { "start": "yarn --cwd apps/frontend start", "next": "yarn --cwd apps/nextapp dev", "dev": "npm-run-all --parallel start next" }` Add the `npm-run-all` development dependency by running: `yarn add --dev -W npm-run-all` Run the following at the root of `yarn-monorepo`: `yarn` > \*\*Note: \*\*This installs the package `npm-run-all` so that you can run multiple projects in parallel locally. This is not needed in production. Then, run the following command to start both the `frontend` and the `nextapp` applications locally: `yarn dev` > This runs the command `npm-run-all --parallel start next` which runs `yarn --cwd frontend start` (`create-react-app` application) and `yarn --cwd nextapp dev` (Next.js application) at the same time. You can now browse to `http://localhost:3000` and `http://localhost:3001` to see each application being served separately from the same repository. ### Deploy to Vercel You will now link a Vercel Project to each frontend site that you would like to have a Deployment for. In this case, it will be for: - the `frontend` folder    - the `nextapp` folder    Let's deploy by using `git`. First we need to remove the `git` repository from the `frontend` and `nextapp` folders, as this comes by default when setting up those frameworks and with a monorepo you only need one repository for all the workspaces. Run the following command in both the `yarn-monorepo/frontend` and `yarn-monorepo/nextapp` folders: `rm -rf .git` Set up `git` from the root `yarn-monorepo` by running: `git init` Add a `.gitignore` file at the root: `touch .gitignore` Paste the following content: `node_modules` Inside your Git hosting provider account that is connected to Vercel, create a `git` repository. Connect it to your `yarn-monorepo` folder using by running `git remote add origin [yourGitRepoURL]` in the root folder and push your changes: `git checkout -b main git add . git commit -m "first commit" git push origin main` Deploy both applications to Vercel from this same repository by [creating a new Vercel Project with Git](https://vercel.com/docs/concepts/deployments/git#deploying-a-git-repository) twice and selecting the repository from the **Import Git Repository** section. Use the following configuration for each Vercel Project:

- For the `apps/frontend create-react-app` application, choose \*\*Create React App \*\*as the framework and \*\*apps/frontend \*\*as the root directory
  
- For the `apps/nextapp Next.js` application, choose \*\*Next.js \*\*as the framework and \*\*apps/nextapp \*\*as the root directory
  

Once each Project is deployed, you will see 2 sites.

### Configure the Ignored Build Step on Vercel

Since you have 2 Vercel Projects connected to the same repository, a `git` push with a change to any part of the repository will cause a Deployment to be triggered in both Projects.

It would be better for a Deployment to be triggered in the `create-react-app` Project only when a change happens in `apps/frontend` and similarly for the Nextjs Project, when a change happens in `apps/nextapp`. This is possible with Vercel by configuring the [Ignored Build Step](https://vercel.com/docs/concepts/projects/overview#ignored-build-step) option inside the **Git** section of the **Project Settings**.

For each Project, set the **Ignored Build Step** to `git diff HEAD^ HEAD --quiet .` and click **Save**.

The reason why you set the directory that you would like this command to return `true` on to `.`, referring to the root folder, is because you have configured the root of the Project to be the application's folder such as `apps/frontend` or `apps/nextapp`.

## That's it!

In this guide, you completed the following tasks:

- Created a monorepo with a workspace for your applications under `apps` and a workspace for your shared code under `packages`
  
- Deployed the monorepo on Vercel as 2 Projects with their own Deployment URL
  
- Configured the \*\*Ignored Build Step \*\*setting on each Project so that Deployments are triggered in each Project only when changes in the Project's folder happen
  

To learn more, please review the following links:

- [Monorepos on Vercel](https://vercel.com/docs/concepts/monorepos)

---

[View full KB sitemap](/kb/sitemap.md)
