Difference between Isolated node_modules and Hoisted node_modules

Cover Image for Difference between Isolated node_modules and Hoisted node_modules
Muhammad Athar

1. Isolated node_modules

  • Definition: Each package or sub-project in a monorepo has its own node_modules directory, containing all the dependencies it needs.
  • Structure:Example:/project /packages /package-a /node_modules react /package-b /node_modules react
    • Each package manages its dependencies independently.
    • Dependencies are installed locally within the node_modules of each package.
    • There is no sharing of dependencies between packages.
  • Advantages:
    • Isolation: Each package is self-contained, so changes in one package's dependencies do not affect others.
    • Predictability: Dependency resolution is straightforward because each package has its own isolated environment.
    • Fewer conflicts: Different versions of the same dependency can coexist in different packages.
  • Disadvantages:
    • Redundancy: Dependencies are duplicated across packages, leading to increased disk space usage.
    • Slower installs: Installing dependencies for each package separately can take more time.

2. Hoisted node_modules

  • Definition: Dependencies are "hoisted" to a common node_modules directory at the root of the project, shared across all packages in the monorepo.
  • Structure:Example:/project /node_modules react /packages /package-a /package-b
    • Dependencies are installed at the root level of the monorepo (or a workspace).
    • Shared dependencies are deduplicated and placed in the root node_modules.
    • Each package may still have its own node_modules for dependencies that cannot be hoisted (e.g., conflicting versions).
  • Advantages:
    • Deduplication: Shared dependencies are installed only once, saving disk space.
    • Faster installs: Dependencies are resolved and installed at the root level, reducing redundancy.
    • Consistency: Ensures that all packages use the same version of shared dependencies.
  • Disadvantages:
    • Dependency conflicts: If two packages require different versions of the same dependency, hoisting may not work as expected.
    • Complexity: Dependency resolution can become more complex, especially when dealing with non-hoistable dependencies or version mismatches.
    • Potential breakage: Packages may accidentally rely on dependencies that are hoisted but not explicitly declared in their package.json.

When to Use Each Approach

  • Isolated node_modules:
    • Use when you need strict isolation between packages.
    • Ideal for projects where packages have highly divergent dependencies or need to be deployed independently.
  • Hoisted node_modules:
    • Use in monorepos or workspaces (e.g., with tools like Yarn Workspaces, Lerna, or PNPM) to optimize for disk space and installation speed.
    • Ideal when packages share many dependencies and need to work together closely.

Tools That Support Hoisting

  • Yarn Workspaces: Automatically hoists shared dependencies to the root node_modules.
  • PNPM: Uses a unique approach with a global store and symlinks, but also supports hoisting.
  • Lerna: Can be configured to hoist dependencies in monorepos.

In summary:

  • Isolated node_modules: Dependencies are installed per package, ensuring isolation.
  • Hoisted node_modules: Dependencies are shared and deduplicated at the root level, optimizing for space and speed.

More Stuff

Cover Image for What's new in JavaScript?

What's new in JavaScript?

Let's take a dive into the world of new addons to our favorite language of the web JavaScript

Muhammad Athar
Cover Image for An Introduction to CSS

An Introduction to CSS

CSS, or Cascading Style Sheets, is a stylesheet language used to apply style and appearance to web documents.

Muhammad Athar