Yarn Workspaces: Centralizing Dependencies in a Monorepo Without Breaking Things
Yarn workspaces let multiple packages share a single dependency tree, but hoisting behavior and migration quirks can catch teams off guard. Here's how to set them up, when to disable hoisting, and how to verify the setup.
04 Feb 2026, 21:00 UTC

In a monorepo with multiple packages, it is common for each package to install its own copy of shared libraries like lodash or react-scripts. The result is a fragmented node_modules, slower installs, and version conflicts when one package upgrades while another pins an older version. Yarn workspaces address this by hoisting compatible dependencies to the root, so every package installs from the same location.
The Monorepo Dependency Problem
When each package in a monorepo pulls in the same dependency independently, disk usage grows and yarn install times climb. In practice, teams often see five copies of the same utility library across five packages, each with a slightly different version range. This makes reproducible builds harder and can surface subtle bugs in CI.
Yarn Workspaces: Configuration & Hoisting Behavior
Enabling workspaces starts with a workspaces field in the root package.json. Yarn accepts a glob, such as ['packages/*']. Once set, yarn install hoists compatible deps to the root node_modules, and packages reference them via symlinks.
workspaces: defines which directories belong to the workspace.nohoist: lists patterns that should stay per-package, helpful for native addons or binaries.- adding
private: trueto a package'spackage.jsonstops it from being published and can change hoisting.
Concrete Example: Three-Package Workspace
Imagine a monorepo with packages at packages/ui, packages/api, and packages/utils. Adding workspaces: ['packages/*'] to the root enables sharing. After yarn install, lodash lives once at the top level, and each package's node_modules/lodash is a symlink to that root copy. To add a dependency only for the UI package, run yarn workspaces add @ui/router. This records the package in packages/ui/package.json and installs it alongside the shared tree. Verify with yarn workspaces status; each line should show the package pointing to the expected root version.
Trade-offs, Limitations & Verification
Not every dep hoists cleanly. Native addons and binaries expecting a local node_modules may break when hoisted; if a binary misbehaves, add its pattern to nohoist, e.g. nohoist: ['**/sharp/**', '**/node-gyp/**'], then re-run yarn install. Yarn Berry (v2+) altered default hoisting compared to Yarn 1.x, so migrating teams should review hoist settings. Peer deps hoisted across packages can cause version mismatches; Yarn 2+ handles this differently than Yarn 1.x. To check impact, run yarn install on a test monorepo before and after enabling workspaces, then compare install time and du -sh sizes of each node_modules. yarn workspaces status should list every package resolving to the root tree.
Getting Started Safely
- Add
workspaces: ['packages/*']to your rootpackage.json. - Run
yarn installand confirm no immediate errors. - Run
yarn workspaces statusand confirm each package resolves to the root dependency tree. - If a binary misbehaves, add its pattern to
nohoistand re-runyarn install. - For Yarn 1.x migrations, audit hoisting settings on a feature branch first.
When configured thoughtfully, Yarn workspaces turn a monorepo's dependency sprawl into a single source of truth, faster installs, and cleaner CI pipelines but the key is verifying hoisting behavior for the packages you actually use.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.