Skip to content

Yarn Workspaces Primer

What is Yarn?

Yarn is a package manager for JavaScript/TypeScript that helps manage dependencies, run scripts, and share code. The v4-monorepo uses Yarn Workspaces to manage multiple packages within a single repository, allowing for efficient dependency sharing and cross-project references.

Key Concepts

Workspaces

Workspaces allow multiple packages to exist within a single repository while sharing a common node_modules directory and allowing for local cross-linking. In v4-monorepo:

  • Each project in apps/ and libs/ is a separate workspace
  • All workspaces share a root node_modules for common dependencies
  • Dependencies are defined in each workspace's package.json

Package Management

Yarn manages packages in two key ways:

  1. Dependency Resolution: Resolves and installs package dependencies based on specifications in package.json files
  2. Hoisting: Moves common dependencies to the root node_modules to avoid duplication

Version Management

The v4-monorepo uses Yarn 4+ with:

  • Yarn PnP (Plug'n'Play) disabled in favor of traditional node_modules
  • Dependency versions locked in the root yarn.lock file
  • Version ranges specified in each workspace's package.json

How Yarn is Used in This Repository

Workspace Configuration

The workspace is configured in the root package.json:

"workspaces": {
  "packages": [
    "apps/**",
    "libs/**",
    "!**/dist/**"
  ],
  "exclude": [
    "**/dist/**",
    "**/node_modules/**"
  ]
}

Dependency Types

The repository uses several types of dependencies:

  • Regular dependencies: Required at runtime (dependencies field)
  • Development dependencies: Required only for development (devDependencies field)
  • Peer dependencies: Required to be provided by consumers (peerDependencies field)
  • Workspace dependencies: References to other packages in the monorepo (dependencies with workspace:* prefix)

Scripts

Scripts are defined in package.json files and can be run using the yarn command:

# Run a script defined in the root package.json
yarn build

# Run a script in a specific workspace
yarn workspace @premia/orderbook build

Common Yarn Commands

Basic Commands

# Install dependencies
yarn install

# Add a dependency to the root package
yarn add <package>

# Add a development dependency to the root package
yarn add -D <package>

# Add a dependency to a specific workspace
yarn workspace @premia/orderbook add <package>

Workspace-specific Commands

# List all workspaces
yarn workspaces list

# Run a command in a specific workspace
yarn workspace @premia/commons-ts build

# Run a command in all workspaces
yarn workspaces foreach run test

Managing Dependencies

# Update dependencies interactively
yarn update-deps

# Check peer dependencies
yarn peer-deps:check

# Install without building native modules
yarn install:skip-builds

Project-Specific Configuration

Each project has its own package.json that defines:

  • Package name and version
  • Dependencies
  • Scripts
  • Other metadata

Example structure for a project's package.json:

{
  "name": "@premia/orderbook",
  "version": "0.0.1",
  "description": "Premia Options & Perps orderbook",
  "main": "src/index.ts",
  "type": "module",
  "dependencies": {
    "@premian-labs/commons": "latest",
    "@premian-labs/connections": "latest",
    "express": "^4.21.2"
  },
  "devDependencies": {
    "@nx/jest": "20.7.2",
    "typescript": "5.7.3"
  },
  "scripts": {
    "format": "yarn run format:biome && yarn format:oxlint"
  }
}

Handling Workspace Dependencies

For local dependencies (workspace dependencies), you can use:

"dependencies": {
  "@premia/commons": "workspace:*"
}

This tells Yarn to use the local version of the package rather than downloading it from a registry.

Publishing Packages

The v4-monorepo includes scripts for publishing packages to GitHub Packages:

# Publish a patch version of commons-ts
yarn publish:commons

# Publish a minor version
yarn publish:commons:minor

# Publish a major version
yarn publish:commons:major

Troubleshooting Yarn

Common Issues

Issue Solution
"Duplicate workspace name" Run yarn workspace:fix-conflicts
"Cannot find module" Re-run yarn install
"Native module build failed" Use yarn install:skip-builds then yarn rebuild:write
"Peer dependency conflict" Check with yarn peer-deps:check and resolve manually
"Conflicting dependency versions" Update dependencies to compatible versions

Yarn Cache

Yarn caches packages to improve performance. If you encounter issues, you can clear the cache:

yarn cache clean

Learn More