CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yarn

Fast, reliable, and secure dependency management tool for JavaScript/Node.js projects

Overview
Eval results
Files

workspace-management.mddocs/

Workspace Management

Commands for managing monorepos and workspaces, enabling multiple packages to be developed together in a single repository.

Capabilities

Workspace Information

Get information about workspaces in the current project.

yarn workspaces info [options]

# Options:
--json                   # Output in JSON format

Usage Examples:

# Show workspace information
yarn workspaces info

# Get JSON output for programmatic use
yarn workspaces info --json

Output Format:

{
  "@company/package-a": {
    "location": "packages/package-a",
    "workspaceDependencies": ["@company/shared"],
    "mismatchedWorkspaceDependencies": []
  },
  "@company/package-b": {
    "location": "packages/package-b", 
    "workspaceDependencies": ["@company/shared"],
    "mismatchedWorkspaceDependencies": []
  },
  "@company/shared": {
    "location": "packages/shared",
    "workspaceDependencies": [],
    "mismatchedWorkspaceDependencies": []
  }
}

Run Commands in All Workspaces

Execute commands across all workspace packages.

yarn workspaces run <command>

Usage Examples:

# Run script in all workspaces
yarn workspaces run build
yarn workspaces run test
yarn workspaces run lint

# Run with yarn run (for scripts defined in package.json)
yarn workspaces run start
yarn workspaces run clean

# Commands run in parallel by default
yarn workspaces run test --coverage

Execution Order:

  • Commands run in dependency order when workspace dependencies exist
  • Independent packages run in parallel
  • If package A depends on package B, B builds before A

Run Commands in Specific Workspace

Execute commands in a specific workspace package.

yarn workspace <workspace-name> <command>

Usage Examples:

# Run script in specific workspace
yarn workspace @company/package-a build
yarn workspace @company/package-a test

# Add dependency to specific workspace
yarn workspace @company/package-a add lodash
yarn workspace @company/package-a add --dev jest

# Remove dependency from specific workspace  
yarn workspace @company/package-a remove lodash

# Install dependencies for specific workspace
yarn workspace @company/package-a install

# Run arbitrary commands
yarn workspace @company/package-a exec ls -la
yarn workspace @company/package-a node scripts/custom.js

Workspace Configuration

Root package.json Setup

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*",
    "tools/*"
  ],
  "devDependencies": {
    "jest": "^29.0.0",
    "eslint": "^8.0.0"
  },
  "scripts": {
    "build": "yarn workspaces run build",
    "test": "yarn workspaces run test",
    "lint": "yarn workspaces run lint",
    "clean": "yarn workspaces run clean"
  }
}

Workspace Package Structure

my-monorepo/
├── package.json (root)
├── yarn.lock (shared)
├── packages/
│   ├── package-a/
│   │   ├── package.json
│   │   └── src/
│   ├── package-b/
│   │   ├── package.json
│   │   └── src/
│   └── shared/
│       ├── package.json
│       └── src/
└── apps/
    └── web-app/
        ├── package.json
        └── src/

Individual Workspace package.json

{
  "name": "@company/package-a",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "test": "jest",
    "clean": "rimraf dist"
  },
  "dependencies": {
    "@company/shared": "1.0.0",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "typescript": "^4.8.0"
  }
}

Workspace Dependencies

Cross-Workspace Dependencies

# Add workspace dependency
yarn workspace @company/package-a add @company/shared

# Add external dependency
yarn workspace @company/package-a add react

# Add dev dependency
yarn workspace @company/package-a add --dev @types/react

package.json Result:

{
  "dependencies": {
    "@company/shared": "1.0.0",
    "react": "^18.0.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.0"
  }
}

Dependency Hoisting

Yarn automatically hoists shared dependencies to the root:

node_modules/           # Root node_modules (hoisted)
├── react/             # Shared by multiple workspaces
├── lodash/            # Shared dependency
└── @company/
    ├── package-a/     # Symlink to packages/package-a
    ├── package-b/     # Symlink to packages/package-b
    └── shared/        # Symlink to packages/shared

Version Conflicts

When workspaces require different versions:

// package-a/package.json
{
  "dependencies": {
    "lodash": "^4.17.21"
  }
}

// package-b/package.json  
{
  "dependencies": {
    "lodash": "^3.10.1"
  }
}

Result:

node_modules/
├── lodash/            # Version 4.17.21 (most common)
└── package-b/
    └── node_modules/
        └── lodash/    # Version 3.10.1 (specific to package-b)

Advanced Workspace Commands

Selective Operations

Using yarn v2+ syntax (if available):

# Run command on packages matching pattern
yarn workspaces foreach --include="@company/*" run build

# Run command excluding certain packages
yarn workspaces foreach --exclude="@company/internal-*" run test

# Run only on packages that changed
yarn workspaces foreach --since="origin/main" run build

# Run with specific concurrency
yarn workspaces foreach --parallel run build

Dependency Management

# Add dependency to root (shared across workspaces)
yarn add --dev eslint

# Add dependency to all workspaces
yarn workspaces run add lodash

# Update dependencies in all workspaces
yarn workspaces run upgrade

# Remove dependency from specific workspace
yarn workspace @company/package-a remove old-dependency

Development Workflow

# Install all workspace dependencies
yarn install

# Build all packages in dependency order
yarn workspaces run build

# Test all packages
yarn workspaces run test

# Lint all packages
yarn workspaces run lint

# Clean all build artifacts
yarn workspaces run clean

# Watch mode for development
yarn workspaces run dev

Workspace Best Practices

Project Structure

monorepo/
├── package.json              # Root config, shared dependencies
├── yarn.lock                 # Single lockfile for entire repo
├── .gitignore               # Shared git ignore
├── .eslintrc.js             # Shared linting config
├── jest.config.js           # Shared test config
├── tsconfig.json            # Base TypeScript config
├── packages/                # Library packages
│   ├── core/
│   ├── utils/
│   └── ui-components/
├── apps/                    # Application packages
│   ├── web-app/
│   ├── mobile-app/
│   └── admin-dashboard/
└── tools/                   # Build tools and scripts
    ├── build-scripts/
    └── dev-tools/

Script Organization

Root package.json:

{
  "scripts": {
    "build": "yarn workspaces run build",
    "build:libs": "yarn workspace @company/core build && yarn workspace @company/utils build",
    "test": "jest --projects packages/*/jest.config.js",
    "test:unit": "yarn workspaces run test:unit", 
    "test:integration": "yarn workspaces run test:integration",
    "lint": "eslint packages/*/src/**/*.{js,ts,tsx}",
    "lint:fix": "yarn lint --fix",
    "typecheck": "yarn workspaces run typecheck",
    "clean": "yarn workspaces run clean",
    "dev": "yarn workspaces run dev",
    "version": "yarn workspaces run version"
  }
}

Dependency Strategy

{
  "devDependencies": {
    // Shared development tools at root
    "typescript": "^4.8.0",
    "jest": "^29.0.0", 
    "eslint": "^8.0.0",
    "@types/node": "^18.0.0"
  },
  "workspaces": [
    "packages/*",
    "apps/*" 
  ]
}

Cross-Package Dependencies

# Link workspace packages properly
yarn workspace @company/app add @company/core
yarn workspace @company/app add @company/utils

# This creates proper symlinks and version references

Publishing Workspaces

# Publish all public packages
yarn workspaces foreach --no-private publish

# Version all packages together
yarn workspaces foreach version patch

# Publish with specific tag
yarn workspaces foreach --no-private publish --tag beta

Common Workspace Patterns

Shared Configuration

// jest.config.js (root)
module.exports = {
  projects: ['<rootDir>/packages/*/jest.config.js'],
  collectCoverageFrom: [
    'packages/*/src/**/*.{js,ts}',
    '!packages/*/src/**/*.d.ts'
  ]
};

// tsconfig.json (root)
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@company/*": ["packages/*/src"]
    }
  },
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" },
    { "path": "./apps/web-app" }
  ]
}

Development Scripts

# Development with watch mode
yarn workspace @company/core dev &
yarn workspace @company/web-app dev &
wait

# Testing across workspaces
yarn test --projects packages/core packages/utils

# Building in correct order
yarn workspace @company/core build
yarn workspace @company/utils build  
yarn workspace @company/web-app build

Install with Tessl CLI

npx tessl i tessl/npm-yarn

docs

cache-management.md

configuration.md

index.md

information-commands.md

package-management.md

project-management.md

registry-operations.md

utility-commands.md

workspace-management.md

tile.json