Use package.json wisely
Tags: package, javascript, bundle
Published: 2022-04-30 17:05:25

### TLDR 
> We are going to explain only the following piece of code

```json
  "peerDependencies": {
    "react": ">=16.8"
  },
  "peerDependenciesMeta": {
    "react": {
      "optional": true
    }
  }
```

### What is the `peerDependencies` field?

Here is the exact quote from npm docs:
> In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a require of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation.

It doesn't make much sense at the first look, so let us continue with an example,
imagine you have an npm package that is just a single react hook, if you think this is stupid, you should take a look at these stupid repositories ([react-hook-form](https://github.com/react-hook-form/react-hook-form), [SWR](https://swr.vercel.app/), [zustand](https://github.com/pmndrs/zustand))
so you need the `react` for your package, cause you need to use builtin hooks (`useState`, `useContext`, ...)
But this makes publishing just a little bit harsh, cause you don't want to build and bundle the react into your output.

let's make it a simple hook, I'm going to make a counter but this time with a reducer :)

```js
import { useReducer } from 'react'

export const useCounter = (initial) => {
  const [counter, inc] = useReducer(s => s+1, initial)
  return [counter, inc]
}
```

If you don't understand why it's a poor idea to bundle the react into my little 5 lines of react-hook, we should chat; it could be a good time for a vacation.
Enough joking; the output bundle size of this tiny section of code would be near the size of the hole react package size.
Besides the size, you can not use multiple versions of the react inside one project, so you are crucially forcing all of your dev users to use the exact react version as you do.

The `peerDependencies` is here to save you a day, in case you passed the react to the`peerDependencies` field in your package.json whenever the developer tries to install your custom package 
npm first looks at your node_modules and see do you have any version of the react installed or not.
If it is not, it put a big warning on your screen that please install 'react' 🥹.
But if found one it checks whether it is compatible with the version you passed as the value of the react (">=16.8") or not, if it is not compatible, you know 🥹, but it won't do anything in the compatible case.

> Note: when I'm writing this post react 18 has been released and it seems to be compatible with the previous ones, so till then `>=16.8` has access to all hooks and can do the job 🚀

I don't know you but I one my installation process to be clean. and here is what `peerDependenciesMeta` is designed for.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1651344915524/AxDI_7_QB.png?auto=compress,format&format=webp)

### What is the `peerDependenciesMeta` field?

Here is the exact quote from npm docs:
> When a user installs your package, npm will emit warnings if packages specified in peerDependencies are not already installed. The peerDependenciesMeta field serves to provide npm with more information on how your peer dependencies are to be used. Specifically, it allows peer dependencies to be marked as optional.

You see, I told you this for eliminating useless warning
In this case, marking a peer dependency as optional ensures npm will not emit a warning if the react package is not installed on the host. 
"This allows you to integrate and interact with a variety of host packages without requiring all of them to be installed." npm said with joy.