avatarJulie J.

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

2214

Abstract

-punctuation">,</span></pre></div><p id="a036"><b>Case #1 (“normal” dependencies)</b></p><p id="e189">I created simple package <i>my-package</i> with following “normal” dependencies:</p><div id="8876"><pre><span class="hljs-attr">"dependencies"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"react-dom"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"18.1.0"</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"loose-envify"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1.0.0"</span> <span class="hljs-punctuation">}</span></pre></div><p id="9b11"><i>react-dom “</i>want” to install <i>[email protected] </i>(current highest compatible with<i> loose-envify@^1.1.0)</i></p><p id="d19e"><i>my-package “</i>want” to install <i>[email protected]</i></p><p id="2e38">I installed <i>my-package </i>with <code>npm install</code>, then verified dependencies tree with <code>npm list --depth=1</code> and this is the output I got:</p><div id="ffb4"><pre><span class="hljs-keyword">my</span>-<span class="hljs-keyword">package</span>@1.<span class="hljs-number">0</span>.<span class="hljs-number">0</span> ├─┬ loose-envify@1.<span class="hljs-number">0</span>.<span class="hljs-number">0</span> │ └── js-tokens@1.<span class="hljs-number">0</span>.<span class="hljs-number">3</span> └─┬ react-dom@18.<span class="hljs-number">1.0</span> ├── loose-envify@1.<span class="hljs-number">4.0</span> ├── react@18.<span class="hljs-number">2.0</span> └── scheduler@0.<span class="hljs-number">22.0</span></pre></div><p id="2e08">Both <i>my-package </i>and <i>react-dom </i>have their own versions of <i>loose-envify</i>— but their behavior is incompatible. If we are sure that it won’t affect our package behavior we can stay with this solution.</p><p id="9c37"><b>Case #2 (peer dependencies with failure)</b></p><p id="d7df">Instead of <i>loose-envify, my-package</i> is now using <i>react</i> package (peer dependency to <i>react-dom</i>) and it has the following dependencies:</p><div id="e1e5"><pre><span class="hljs-attr">"dependencies"</span><span class="hljs-punctuation"

Options

:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"react-dom"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"18.1.0"</span> <span class="hljs-attr">"react"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"18.0.0"</span><span class="hljs-punctuation">,</span> <span class="hljs-punctuation">}</span></pre></div><p id="aaaf"><i>react-dom “</i>want” to install <i>[email protected]</i> (current highest compatible with <i>react@^18.0.0)</i></p><p id="5cf0"><i>my-package “</i>want” to install <i>[email protected].</i></p><p id="0b69"><i>[email protected]</i> is incompatible with the <i>[email protected].</i></p><p id="6fcb">As a result, any attempt to install it with an incompatible <i>react </i>version (<i>[email protected] </i>or <i>[email protected]) </i>will end with failure:</p><div id="d243"><pre>npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: react-dom@<span class="hljs-number">18.2</span>.<span class="hljs-number">0</span> npm ERR! Found: react@<span class="hljs-number">18.0</span>.<span class="hljs-number">0</span> npm ERR! node_modules/react npm ERR! react@<span class="hljs-string">"18.0.0"</span> from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer react@<span class="hljs-string">"^18.2.0"</span> from react-dom@<span class="hljs-number">18.2</span>.<span class="hljs-number">0</span> npm ERR! node_modules/react-dom npm ERR! react-dom@<span class="hljs-string">"18.2.0"</span> from the root project npm ERR! npm ERR! Conflicting peer dependency: react@<span class="hljs-number">18.2</span>.<span class="hljs-number">0</span> npm ERR! node_modules/react npm ERR! peer react@<span class="hljs-string">"^18.2.0"</span> from react-dom@<span class="hljs-number">18.2</span>.<span class="hljs-number">0</span> npm ERR! node_modules/react-dom npm ERR! react-dom@<span class="hljs-string">"18.2.0"</span> from the root project npm ERR! npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution.</pre></div></article></body>

Understanding peer dependencies in JavaScript

Photo by Markus Spiske on Unsplash

In the package.json file, we can see a few fields dedicated to dependencies. One of them which is often not fully understandable is peer dependency.

It may happen someday, that you will be developing your package. In this situation, there will be users installing your packages in their projects.

Your package has its dependencies, but what if user adds the same dependency but in a different version? Their behaviors might be incompatible. To prevent your users from using wrong versions you can use peer dependency and block installation when packages are incompatible.

Let’s explain it on the react-dom package which can be added to your package. It has both “normal” dependencies and peerDependencie defined so it is good to highlight differences between them.

[email protected] used in the examples has the following dependencies in the package.json:

  "dependencies": {
    "loose-envify": "^1.1.0",
    "scheduler": "^0.21.0"
  },
  "peerDependencies": {
    "react": "^18.0.0"
  },

Case #1 (“normal” dependencies)

I created simple package my-package with following “normal” dependencies:

"dependencies": {
    "react-dom": "18.1.0",
    "loose-envify": "1.0.0"
  }

react-dom “want” to install [email protected] (current highest compatible with loose-envify@^1.1.0)

my-package “want” to install [email protected]

I installed my-package with npm install, then verified dependencies tree with npm list --depth=1 and this is the output I got:

my-package@1.0.0
├─┬ loose-envify@1.0.0
│ └── js-tokens@1.0.3
└─┬ react-dom@18.1.0
  ├── loose-envify@1.4.0
  ├── react@18.2.0
  └── scheduler@0.22.0

Both my-package and react-dom have their own versions of loose-envify— but their behavior is incompatible. If we are sure that it won’t affect our package behavior we can stay with this solution.

Case #2 (peer dependencies with failure)

Instead of loose-envify, my-package is now using react package (peer dependency to react-dom) and it has the following dependencies:

"dependencies": {
    "react-dom": "18.1.0"
    "react": "18.0.0",
  }

react-dom “want” to install [email protected] (current highest compatible with react@^18.0.0)

my-package “want” to install [email protected].

[email protected] is incompatible with the [email protected].

As a result, any attempt to install it with an incompatible react version ([email protected] or [email protected]) will end with failure:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: react-dom@18.2.0
npm ERR! Found: react@18.0.0
npm ERR! node_modules/react
npm ERR!   react@"18.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.2.0" from react-dom@18.2.0
npm ERR! node_modules/react-dom
npm ERR!   react-dom@"18.2.0" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: react@18.2.0
npm ERR! node_modules/react
npm ERR!   peer react@"^18.2.0" from react-dom@18.2.0
npm ERR!   node_modules/react-dom
npm ERR!     react-dom@"18.2.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
JavaScript
Npm Package
Nodejs
Peer Dependencies
Recommended from ReadMedium