When was the last time you stopped to think about the cost of a new third-party package that you’re adding into your process?
Where do you recommend balancing between “not invented here” syndrome (NIH) and using packages just because they exist? I always come back to the “left-pad incident” as an extreme example to avoid the latter, but where should we be drawing the line between the two?

While npm doesn’t publish statistics of the number of packages in its registry, in 2019 they passed the 1 million package mark. That means we have at least 1 million packages we could possibly consider using.
That is utterly too many packages. I’m sure we’ve all contributed in some way to the proliferation of a module for everything, but where can we start drawing the line and how do we actually determine whether we should be using one package over another over writing it ourselves?
Some considerations that I’ve been thinking about when looking at third-party JavaScript modules:
- Can we actually do it all on our own?
- What’s the cost of maintenance and bug fixes?
- How will a third-party module affect bundle size?
- Will the effort to build an equivalent be too high?
- Do we already have a package that satisfies this use case?
- Is there an equivalent standard API?
- Does the module actually work as advertised?
Internal ability and understanding
I’m currently torn between writing some (what I would consider) simple DOM layout measurements for tooltip positioning versus reaching for floating-ui to do it for me. The library actually has much more than I need, but it’s tree-shakeable, so maybe that’s okay.
I’m confident that I can write and maintain my own measurements and ResizeObserver
, but does my team all feel the same? But then again, if they can’t, maybe I should be helping and encouraging them to learn.
There’s no single answer to all of this and it should be carefully taken into consideration. Just because we can, doesn’t mean we should.
Maintenance and bug fixing
Extending from the internal ability and understanding, reaching for a library without the knowledge of what it’s actually doing can be worse than copy/pasting from StackOverflow. At least with copying code from somewhere, while you didn’t write it, it’s now yours and your team’s to understand and maintain. If it ends up having a bug in it, you are responsibe and should be able to fix and deploy it at any time.
When pulling in a third-party module, you’re at the mercy of the open source authors & maintainers – even if you create a pull request, will it get fixed, merged, and deployed for you? Would you even have been able to get ramped up on contributing to the open source repository in a realistic timeframe?
Let’s say you decide to fork a library and maintain it internally. Well now you’ve got an issue of how its repository is set up, standards, lint rules, etc. There are many concerns to consider when forking.
Bundle size
One of my first stops when evaluating a third-party package is BundlePhobia. This gives me a general idea of how much a the package will increase my overall bundle size after building and deploying for production, as well as show what other dependencies it has and how their makeup affects the build.
- Is the relative size of the package realistic for what I’m expecting it to do?
- Do any of its dependencies overlap with what I’m already using, and thus may not actually increase my final bundle size as much as this says?
Is the juice worth the squeeze?

I have a team rebuilding our core shared component library at work and we have a strict mandate to ensure WCAG 2.0 accessibility standards. The team knows what they’re doing and can absolutely succeed at meeting those on their own. However, while building the previous iteration of the library, the <DatePicker />
component took nearly three months to build.
I challenged the team, despite their hesitation about ARIA, to try using react-aria, a major library of React hooks that aid in providing accessible UI primitives for design systems. One person came back on the same day with a prototype of a fully accessible <DatePicker />
and stated that it took them about two hours to build what previously took over two months.
Essentially, “is the juice worth the squeeze” means we can determine whether the output is worth the effort. In cases like the above, I can safely answer “no” and move forward with pulling in the dependency. Other times, maybe not.
Duplicate concerns
Do we already have a package that fulfills this use case? I can’t even count how many applications I’ve seen running a combination of state management libraries like Redux, Redux Toolkit, React Query, and Zustand (among a scattering of others). Pick one and stick with it; don’t reach for a new library just because you heard it’s new.
Standard APIs
Is there a standard API that can already do much of the same thing? Check your browser support matrix via MDN or caniuse.com and consider standars in favor of older packages that fulfill the same purposes. Here are just a few of the packages and their standard equivalents that came up for me recently when auditing bundle bloat in applications:
Third-party library | Equivalent standard |
---|---|
dateformat | Intl.DateTimeFormat |
axios | fetch |
uuid | crypto.randomUUID() |
lodash | you might not need lodash |
Code review
Have we actually looked at the source of the module and verified that it does what it says? Does have tests asserting its behavior works as advertised, or has it been thrown together without concern?
We should actually read the code. Maybe it’s great, but maybe it’s also fundamentally flawed and we might pick that up by reading the code. Or just maybe we realize that it’s simple and we could have written this ourselves…
What am I forgetting and what considerations do you make when pulling in new third party packages? Or did you forget to think through any of that today?