Use package.json wisely

Control the size of your exports

ยท

3 min read

TLDR

We are going to explain only the following piece of code

  "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, SWR, 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 :)

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 thepeerDependencies 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.

image.png

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.

ย