Skip to content
Yarn Package Manager Guide — Workspaces, Plug'n'Play, and Performance

Yarn Package Manager Guide — Workspaces, Plug'n'Play, and Performance

DodaTech Updated Jun 7, 2026 7 min read

Yarn is a JavaScript package manager that improves on npm with deterministic installs, workspaces for monorepo management, Plug’n’Play for zero-install projects, and offline caching — all while being a drop-in replacement for npm workflows.

What You’ll Learn

  • How Yarn differs from npm and why deterministic installs matter
  • Setting up workspaces for monorepo projects
  • Using Plug’n’Play (PnP) for faster, zero-install development
  • Enforcing project rules with constraints
  • Running tools without install with yarn dlx
  • Migrating an existing npm project to Yarn

Why Yarn Matters

npm’s early versions had inconsistent installs — node_modules could differ between developers because dependency resolution wasn’t deterministic. Yarn introduced yarn.lock, lockfile validation, offline caching, and parallel downloads — making installs repeatable and faster. For monorepo projects, Yarn workspaces let you manage multiple packages in one repository with shared node_modules. DodaTech uses Yarn workspaces in Doda Browser’s extension SDK — the core SDK, React bindings, and TypeScript types are separate packages in one repo that share dependencies through Yarn workspaces.

    flowchart LR
    A[JavaScript & TypeScript Basics] --> B[Yarn]
    B --> C[Deterministic Installs]
    B --> D[Workspaces]
    B --> E[Plug'n'Play]
    B --> F[Constraints]
    C --> G[yarn.lock]
    D --> H[Monorepo Management]
    E --> I[Zero-Install]
    style B fill:#2c8ebb,color:#fff
  
Prerequisites: Solid JavaScript and TypeScript knowledge. Experience with npm or another package manager.

Core Concepts

Installation and Basic Commands

# Install Yarn globally
npm install -g yarn

# Or use the preferred method (Corepack — Node.js 16+)
corepack enable
corepack prepare yarn@stable --activate

# Initialize a project
yarn init

# Basic commands — familiar if you know npm
yarn add express            # Install a dependency
yarn add -D typescript      # Dev dependency
yarn remove lodash          # Remove a dependency
yarn upgrade react          # Upgrade a package
yarn install                # Install all dependencies

Output: Yarn creates yarn.lock — a deterministic lockfile that ensures every developer gets exactly the same dependency tree. Unlike npm’s package-lock.json, Yarn’s lockfile is guaranteed to produce identical installs across machines.

Workspaces (Monorepo Support)

// package.json (root)
{
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}
// packages/core/package.json
{
  "name": "@myapp/core",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.0.0"
  }
}

// packages/web/package.json
{
  "name": "@myapp/web",
  "version": "1.0.0",
  "dependencies": {
    "@myapp/core": "workspace:^",
    "react": "^18.0.0"
  }
}
# Install all workspace dependencies into a single shared node_modules
yarn install

# Run a script in a specific workspace
yarn workspace @myapp/core build

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

# Output:
# [@myapp/core]: PASS tests/index.test.ts
# [@myapp/web]: PASS tests/app.test.ts

Output: Yarn hoists shared dependencies to a root node_modules, reducing disk usage. The workspace:^ protocol ensures @myapp/core is linked locally, not fetched from npm. Changes in core are immediately available in web without publishing.

Plug’n’Play (PnP)

# Enable PnP in an existing project
yarn set version stable
yarn install

# PnP mode — no node_modules directory!
// With PnP, packages are stored in a zip archive
// .yarn/cache/  — contains all package zip files
// .pnp.cjs      — resolution map (replaces node_modules)

Output: PnP eliminates node_modules entirely. Packages are stored as zip files in .yarn/cache/ and resolved instantly via .pnp.cjs. This means:

  • No node_modules to scan — resolution is instantaneous
  • Zero install — commit .yarn/cache/ to Git; new clones run immediately
  • Strict module boundaries — you can’t import packages you didn’t declare in package.json

Constraints

// constraints.pro — Yarn 4+ constraint engine
// Enforces rules across all workspace packages

const { Yarn } = require("@yarnpkg/constraints");

module.exports = {
  async constraints({ Yarn }) {
    // Every package must have a description
    for (const workspace of Yarn.workspaces()) {
      if (!workspace.manifest.description) {
        workspace.set("description", "TODO: Add description");
      }
    }

    // Dependencies must use exact versions
    for (const workspace of Yarn.workspaces()) {
      for (const [name, range] of workspace.manifest.dependencies) {
        if (range.startsWith("^") || range.startsWith("~")) {
          workspace.error(`${name} should use exact version, not range`);
        }
      }
    }
  },
};
# Check constraints
yarn constraints

# Apply fixes automatically
yarn constraints --fix

Output: Constraints are code-based rules that run across all workspace packages. They catch inconsistencies — missing descriptions, incorrect version ranges, missing dependencies — and can auto-fix them.

yarn dlx

# Run a package without installing it globally
yarn dlx create-react-app my-app

# Similar to npx, but faster because Yarn caches the package
yarn dlx prisma generate

Migration from npm

# In an existing npm project
yarn import    # Generate yarn.lock from package-lock.json
yarn install   # Install using Yarn

# Or migrate completely
rm package-lock.json node_modules
yarn init
yarn install   # Creates fresh yarn.lock

Common Mistakes

  1. Mixing npm and Yarn lockfiles: Don’t commit both package-lock.json and yarn.lock. Delete the npm lockfile when migrating. Having both causes unpredictable installs.

  2. Forgetting to run yarn install after pulling changes: Yarn’s install is not automatic. Always run yarn install after git pull to update dependencies.

  3. Using PnP with tools that expect node_modules: Some build tools and SDKs don’t support PnP. Set nodeLinker: "node-modules" in .yarnrc.yml for compatibility.

  4. Not scoping workspace package names: Workspace packages should be scoped (@myapp/core, @myapp/web) to avoid name collisions with npm packages.

  5. Committing .yarn/cache/ to Git without understanding size impact: PnP’s cache folder can be large. It’s worth committing for zero-install benefits, but exclude it in .gitignore if your team prefers faster clones.

Practice Questions

  1. What problem does yarn.lock solve? Answer: It locks dependency versions to ensure every developer and CI environment gets exactly the same dependency tree — preventing “works on my machine” issues.

  2. How do Yarn workspaces help manage monorepos? Answer: Workspaces install shared dependencies once (hoisting), link local packages without publishing, and allow running scripts across all packages with yarn workspaces foreach.

  3. What is Plug’n’Play and when should you use it? Answer: PnP eliminates node_modules by storing packages as zip files and resolving imports via .pnp.cjs. Use it for faster installs and stricter module boundaries.

  4. How do constraints improve monorepo maintenance? Answer: Constraints enforce policy across all workspace packages — ensuring consistent versioning, required fields, and dependency rules through code, not manual review.

Challenge

Set up a monorepo: create a Yarn workspace with three packages (@app/core, @app/server, @app/web), configure shared TypeScript config, add a constraint that enforces all packages have a license field, enable PnP mode, and write a workspace script that builds all packages in dependency order.

FAQ

Is Yarn faster than npm?
: Yarn Modern (v4+) is generally faster than npm, especially for cached installs and workspace operations. Yarn Classic (v1) is slower but more widely known.
Should I migrate from npm to Yarn?
: If you need workspaces, PnP, or deterministic installs, yes. For simple projects, npm and Yarn are comparable.
What is Yarn Berry?
: Yarn Berry is Yarn v2+, the modern rewrite. “Classic” refers to Yarn v1. Modern Yarn (v4) is the recommended version.
Does Yarn work with pnpm?
: No. Yarn and pnpm are separate package managers. Choose one for your project.
Can I use Yarn with Docker?
: Yes. For PnP projects, copy .yarn/cache/ and .pnp.cjs into the Docker image. For node_modules mode, run yarn install during the build.

Try It Yourself

# Create a test project
mkdir yarn-demo && cd yarn-demo
yarn init -y
yarn add express

# Compare lockfile format
cat yarn.lock | head -20
# Note the differences from package-lock.json

# Enable workspaces
# Edit package.json to add "workspaces": ["packages/*"]
mkdir packages/core packages/web
# Add package.json files and test workspace linking

What’s Next

TopicDescription
Node.js
Package management for Node.js apps
Vite
Build tool that pairs well with Yarn

Related topics: JavaScript, TypeScript, Node.js, npm

What’s Next

Congratulations on completing this Yarn tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro