DEV Community

Cover image for How I Choose a Library Before Adding It to a Project
Aleksandra Dudkina
Aleksandra Dudkina

Posted on Originally published at aleksandradudkina.hashnode.dev

How I Choose a Library Before Adding It to a Project

Downloads, maintenance, framework support, API, styling and the one thing I really don't want to do - reverse-engineer a library just to use it

When I started working with frontend libraries, my selection process was pretty simple:

  1. Google the problem

  2. Find a library that seems to solve it

  3. npm install

  4. Start coding

And sometimes this works perfectly.

But the more libraries I used in real projects, the more I realised that installing one is the easy part.

The real question is:

Will I still be happy with this library several months later?

A library might look perfect from the README and still become painful once you discover that it hasn't been updated for two years, doesn't properly support your React version, exposes an API that doesn't fit your use case, or is almost impossible to customise.

So now, before adding a new library to a project, I usually check a few things first.

1. How many downloads does it have?

One of the first places I go is npm.

Weekly downloads are not a guarantee that a library is good, but they give me a rough idea of how widely it is used.

My very approximate scale looks like this:

Weekly downloads How I interpret it
1M+ Very widely used
100k–1M Well established
10k–100k Totally reasonable, especially for a niche library
<10k I want to investigate more before adding it

These numbers are not strict rules.

A very specific library might only have 5,000 weekly downloads and still be the best solution for its particular problem.

A new library might also be technically much better than an older one with millions of downloads.

And downloads don't necessarily mean that millions of developers intentionally selected this package. Some packages are installed as dependencies of other packages.

So I don't use downloads as:

low downloads = bad library

I use them more as:

low downloads = I should probably check the rest of the signals more carefully.

The more important or deeply integrated the dependency will be, the more cautious I am.

For example, I care much more about this when choosing a table library, router or state-management solution than when installing a tiny helper package.

2. When was the latest version released?

The next thing I check is the date of the latest release.

A library can have millions of downloads but still be practically abandoned.

As a very rough benchmark, I think about it like this:

  • updated during the last 3 months → great

  • 3–6 months ago → completely normal

  • 6–12 months ago → I start checking the repository

  • more than a year ago → I want to understand why

Again, this doesn't automatically mean:

no releases for a year = dead library

Some libraries are simply mature.

If a small utility has been stable for years and the JavaScript API it depends on hasn't changed, there might genuinely be nothing to release.

But for something tightly connected to React, bundlers, browser APIs or other actively changing tools, a long period without releases makes me more suspicious.

At this point I usually open GitHub and check:

  • Are there recent commits?

  • Are pull requests being merged?

  • Are maintainers answering issues?

  • Are new React / TypeScript versions mentioned?

  • Is there a huge queue of old unresolved bugs?

The last release date alone doesn't tell the full story.

A library released six months ago with active maintainers can be healthier than a library that published a tiny patch yesterday but has 500 ignored issues.

3. Does it actually support my framework?

This sounds obvious, but I have learned not to assume it.

In my case, I'm mostly working with React.

So if I'm evaluating a library, I want to know:

  • Does it explicitly support React?

  • Which React versions?

  • Does it have a React-specific package?

  • Are there React examples in the documentation?

  • Does the documentation use current React patterns?

For example, seeing:

npm install some-library
Enter fullscreen mode Exit fullscreen mode

is not enough for me.

I want to see something like:

import { SomeComponent } from "some-library/react";

export function MyComponent() {
  return <SomeComponent />;
}
Enter fullscreen mode Exit fullscreen mode

Even better if there is a dedicated React section explaining the integration.

I also check peerDependencies when compatibility matters.

If I'm using React 19 and the package declares:

{
  "peerDependencies": {
    "react": "^17 || ^18"
  }
}
Enter fullscreen mode Exit fullscreen mode

I wouldn't immediately reject it, but I would investigate before putting it into production.

Maybe React 19 works perfectly and they simply haven't updated the peer dependency yet.

Or maybe there is a real compatibility problem.

I prefer knowing this before I've built half a feature around the library.

4. What does the API actually look like?

A library can solve exactly the problem I have and still expose an API I don't want to work with.

Before installing it, I try to understand how I would implement my actual use case.

Not the easiest example from the documentation.

My use case.

Let's say I'm choosing a table library.

I might need:

  • sorting

  • filtering

  • column resizing

  • row selection

  • virtualisation

  • controlled state

  • custom cells

I want to understand whether these are first-class features or whether I will have to fight the library.

I usually look through:

  • exported components

  • hooks

  • methods

  • callbacks

  • configuration options

  • controlled / uncontrolled state

  • TypeScript types

For example, there is a big difference between an API like:

<Table
  data={data}
  columns={columns}
  onRowSelect={setSelectedRows}
/>
Enter fullscreen mode Exit fullscreen mode

and one where implementing the same behaviour requires several adapters, custom plugins and undocumented internal methods.

That doesn't necessarily make the second library bad.

Sometimes more complex APIs give you much more control.

But I want to understand that trade-off before choosing it.

Another thing I check is whether the API matches how I expect the feature to evolve.

Maybe today I only need a simple date picker.

But I already know that soon I will probably need:

  • ranges

  • disabled dates

  • localisation

  • controlled state

  • custom input

  • custom calendar cells

If the library supports only my current simplest scenario, I might have to replace it very soon.

5. Can I customise the styles?

This depends a lot on the project.

Sometimes the default UI is completely fine.

Sometimes I need the component to look exactly like our design system.

In the second case, styling becomes one of the most important criteria.

Before choosing the library I check whether I can use:

  • className

  • inline style

  • CSS variables

  • data-* attributes

  • custom components

  • render props

  • theme configuration

I also want to understand how difficult overriding the default styles will be.

If changing a simple border requires:

.some-library-wrapper
  .some-library-container
  .some-library-component
  .some-library-inner-element {
  border: none !important;
}
Enter fullscreen mode Exit fullscreen mode

that's already a warning sign 🙂

This is one of the reasons I often like headless or primitive-based libraries.

They might require more work initially, but they usually give much more control over the final UI.

Of course, this isn't always necessary.

If I'm building an internal admin panel and the library's default design is acceptable, full styling control might not matter at all.

The important thing is to check it before choosing the library if customisation is part of the requirements.

6. How good is the documentation?

This is probably one of the most important things for me.

Because eventually something will not work.

And at that moment I don't want my only option to be:

Open library's repository and start investigating the source code.

I don't expect documentation to explain every possible edge case.

Sometimes reading library source code is actually useful.

But I don't want it to be required for basic usage.

Good documentation for me usually has:

  • a clear getting started guide

  • API reference

  • examples

  • TypeScript examples

  • explanations of configuration options

  • framework-specific documentation

  • migration guides between major versions

  • examples for less obvious use cases

One thing I particularly like is when documentation explains why something works a certain way instead of only showing code.

For example:

<Component option={true} />
Enter fullscreen mode Exit fullscreen mode

is useful.

But:

option enables controlled behaviour and should be used together with onChange

is much more useful.

I also search the docs for the exact feature I need.

If the library says it supports custom rendering, but searching for “custom rendering” gives me one two-line example with no explanation, I know I might spend more time exploring the repository later.

My rule is roughly:

Reading the source code for a complex edge case is fine.

Reading the source code just to understand the public API is not.

What I don't treat as a deal-breaker

There are a few things I try not to judge in isolation.

Low npm downloads

Fine for a niche or relatively new package.

No release for several months

Fine if the library is stable and the repository is still maintained.

Small GitHub community

Fine if the maintainers are active and the project is focused.

Complex API

Fine if the problem itself is complex and the API gives me the flexibility I need.

This is why I don't really have one metric like:

If the package has less than X downloads, don't use it.

Choosing a dependency is more about putting all the signals together.

Final checklist

Before adding a library, I usually investigate:

  • How many weekly npm downloads does it have?

  • When was the last version released?

  • Is the repository still actively maintained?

  • Does it support my framework and its current version?

  • Is there framework-specific documentation?

  • Does the API cover the use cases I actually need?

  • Can I customise the styles if necessary?

  • Are the docs detailed enough?

  • If something goes wrong, will I be able to understand how the library works without reverse-engineering the whole repository?

Final takeaway

Choosing a library isn't only about:

npm install
Enter fullscreen mode Exit fullscreen mode

and getting the first example working.

The dependency becomes part of your project.

Other developers will need to work with it. You may need to update it. Requirements will change. Bugs will happen.

So I try to choose libraries not only based on whether they solve the problem today, but also on whether I expect them to remain comfortable to work with later.

Because replacing a library after one quick experiment is easy.

Replacing it after it has spread through half of your application is a very different task.

Top comments (0)