Episode 6: Using Yarn Workspaces to Manage Monorepos

What Are Workspaces?

Workspaces are a powerful way to manage multiple packages within a single repository. They allow packages to:

  1. Interact as Dependencies:

    • Automatically link packages together as dependencies via symlinks.
  2. Streamline Installation:

    • Use a single yarn install command to link all packages.
  3. Optimize Node Modules:

    • Share dependencies between packages through hoisting, reducing duplication and saving disk space.

Key Advantages of Workspaces

  • Simplified Management: All packages in one repository interact seamlessly.

  • Space Optimization: Dependencies are shared across packages.

  • Improved Performance: Faster installations and smaller disk usage.

  • Automation: Symlinks are created automatically.


Setting Up Workspaces with Yarn

Initial Directory Structure

monorepo-project/
│
├── packages/
│   ├── moduleA/
│   │   ├── index.js
│   │   └── package.json
│   └── moduleB/
│       ├── index.js
│       └── package.json
└── package.json (root)

1. Creating a Root package.json

Navigate to the root directory of your repository and initialize a package.json:

yarn init -y

This creates a basic package.json. Next, make the following modifications:

Root package.json Example

{
  "name": "monorepo-project",
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*"
    ]
  }
}

Explanation

  • "private": true: Prevents accidentally publishing the entire repository to npm.

  • "workspaces":

    • packages/* is a glob pattern that automatically includes all subdirectories under packages.

    • This simplifies adding new modules.


2. Creating Module-Specific package.json Files

moduleB/package.json

{
  "name": "moduleB",
  "version": "1.0.0",
  "main": "index.js"
}

moduleA/package.json

{
  "name": "moduleA",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "moduleB": "1.0.0"
  }
}

3. Running yarn install

Run the following command in the root directory:

yarn install

This automatically:

  • Creates symlinks between the packages (e.g., moduleA → moduleB).

  • Installs any external dependencies and hoists shared ones to the root node_modules folder.


4. Adding Code to Modules

moduleB/index.js

console.log('This is module B');

moduleA/index.js

console.log('This is module A');
require('moduleB');

5. Running Module A

Navigate to moduleA and run:

node packages/moduleA/index.js

Output:

This is module A  
This is module B

Benefits of Workspaces

  1. Real-Time Updates:

    • Changes in moduleB are immediately reflected in moduleA without manual reinstallation.
  2. Effortless Collaboration:

    • Developers cloning the repository can run yarn install to set up all packages instantly.
  3. Simplified .gitignore:

    • You can now ignore all node_modules folders with a single rule:

        node_modules/
      

Final Thoughts

Yarn Workspaces provide a clean, scalable solution to managing monorepos. They automate linking and dependency sharing, making it easier to develop, test, and deploy multi-package projects.

In the next lessons, we’ll dive into hoisting and more advanced workspace optimizations. 🚀