7 min read

I Stopped Installing npm Packages for Everything — Here's What Happened

JavaScriptDeveloper ToolsPerformanceCode QualitySnippet Ark

I deleted 47 npm packages from my last project. The app didn't break. It actually got faster. And I realized I'd been using npm like a emotional support animal — the packages weren't solving problems I had, they were solving problems I was afraid of someday maybe having.

This isn't going to be one of those "npm is bloat" rants. I'm not telling you to hand-roll a web framework. But after years of watching my node_modules folder grow fatter while my actual understanding of my own code shrank, I started asking a different question: what happens if I just write this myself?

Spoiler: the answer surprised me.

How I Got Here

I was building a simple image resizer for a side project. Needed to crop, resize, convert format. Standard stuff. My first instinct — like any good developer in 2026 — was to reach for Sharp. It's great. Battle-tested. 26 million weekly downloads.

But I was building an Electron app. Adding Sharp meant adding native dependencies. Build times went from 12 seconds to 3 minutes. My CI pipeline needed different system libraries. Two teammates on Windows couldn't even install it without troubleshooting for an hour.

For a crop and resize.

I spent an afternoon writing 80 lines using Canvas API. It handled everything I needed. Zero dependencies. Zero build headaches. And I finally understood, line by line, exactly how my image pipeline worked.

That experience started a habit. Every time I reached for a package, I'd ask: "Is this actually hard, or do I just not want to write it?"

The Audit That Hurt

I ran npm ls --depth=0 on my last production app. Then I sat down and evaluated every single package: do we actually need this, or is it here by inertia?

Here's what I found:

  • lodash — using maybe 5 functions. ES6+ covers most of them natively now. Replaced with 30 lines of utility functions.
  • moment.js — still using this? In 2026? Intl.DateTimeFormat and a 10-line formatter did everything we needed.
  • axios — using it for basic GET requests. fetch() in Node 22 is solid. No more quirky error handling from axios.
  • classnames — 26 lines of code. We were importing a 2KB package for 26 lines we could write in 2 minutes.
  • uuid — crypto.randomUUID() has been in the platform for years.

Don't get me wrong — these are all excellent packages. But excellent ≠ necessary for your use case.

When You Should Definitely Use a Package

I'm not a purist. There are things you should never write yourself:

  • Cryptography — please don't roll your own RSA
  • Date/time parsing — time zones are a nightmare and I respect anyone who maintains a library for them
  • Complex UI components — data tables, rich text editors, date pickers. Don't build these unless you have a really good reason.
  • Protocol implementations — if you need OAuth, use a library. Please.
  • Database drivers — let the experts handle the edge cases

The rule isn't "never use packages." The rule is "use packages for things that are genuinely hard, not for things that are merely tedious."

The Hidden Costs of Packages

When you install a package, you're not just downloading code. You're accepting a bundle of hidden costs:

Maintenance Tax

Every package is a dependency you need to track. Security alerts. Breaking changes. Deprecations. Each one adds cognitive load. I spent two full days last year just updating packages and fixing breaking changes. Two days I'll never get back.

The Left-Pad Problem

Remember when one developer unpicked 11 lines of code and the internet broke? That fragility hasn't gone away. In 2026, we have better infrastructure, but supply chain attacks are more sophisticated than ever. Every package you add is a trust decision about hundreds of people you've never met.

Bundle Bloat That Compounds

One package pulls in another, which pulls in another. I audited a project that listed 15 direct dependencies. The resolved dependency tree had 482 packages. Four hundred and eighty-two. For a relatively simple CRUD app.

Context Switching

Every time you use a package's API, you're switching context to someone else's documentation. Someone else's conventions. Someone else's way of solving problems. That's mental overhead you don't notice until it's gone.

How to Start Owning Your Code

I'm not saying go delete everything today. Here's a more sustainable approach.

Start With One Replacement

Pick the package you're least happy with — maybe it's one that updates too often, or has a weird API, or solves a problem you now have native APIs for. Replace it with your own implementation. See how it feels.

I started with classnames. It took me 2 minutes to write. I felt stupid for not doing it sooner. That small win snowballed into auditing my entire dependency tree.

Build Your Own Snippet Library

The reason we install packages instead of writing code is that writing code takes time. Unless you already have it.

This is where Snippet Ark became essential for me. I started saving every utility function I wrote — the URL formatter, the debounce, the deep clone, the localStorage wrapper. Over time, I built a personal standard library that knows exactly how I code.

Next time I need to format a date, I don't install a package. I open Snippet Ark, grab my formatter, and I'm done in 30 seconds. The code is mine. I understand it. It's zero dependencies. And if it breaks, I know exactly why.

Audit by Category

Go through your package.json section by section:

  • devDependencies — can you combine any? Are all the ESLint plugins still active? Do you need that specific Babel preset?
  • UI packages — are you using 10% of a component library? Could you replace it with a few custom components?
  • Utility packages — which of these does the platform provide natively now?
  • Middleware — do you need all those Express middleware packages, or are you just adding them out of habit?

The 30-Minute Rule

Before installing a package, spend 30 minutes writing the implementation yourself. If it takes longer than that, install the package. You'll be surprised how often you finish in under 30 minutes — and now you have code you own.

What Happened When I Did This

After six months of conscious dependency reduction:

  • Bundle size dropped from 1.2MB to 480KB
  • Build time went from 8 minutes to 2.5 minutes
  • Zero dependency-related incidents in production
  • I shipped features faster — because I wasn't spending days updating packages

But the biggest win wasn't measurable. It was the feeling of understanding my codebase again. Every function, every import, every edge case — I knew where it came from because I'd written it or consciously chosen it.

The Platform Is Good Now

Part of why this approach works in 2026 is that JavaScript/the platform has seriously caught up. Things that required libraries a few years ago are now built in:

  • Array.toSorted(), Array.toReversed() — no more lodash for basic array ops
  • structuredClone() — deep cloning without a library
  • crypto.randomUUID() — UUID generation is a one-liner
  • fetch() everywhere — Node, browsers, Deno, Bun
  • Intl.DateTimeFormat — date formatting without moment.js
  • :has() selector — CSS that used to require JavaScript

These aren't experimental features. They're stable, well-documented, and performant. The platform has quietly made hundreds of packages obsolete.

It's Not About Purity

Let me be clear: I still use packages. My projects use React, Next.js, Tailwind, and plenty of other dependencies. I'm not running a minimalist manifesto — I'm running a business, and shipping matters more than ideological purity.

But I've stopped reaching for npm as my first instinct. I think about whether I actually need the dependency, or whether the platform — or my own growing library — already has what I need.

The result? Less node_modules. Less tech debt. And way more confidence in the code I ship.


Here's my challenge to you: open your package.json and pick one dependency to remove today. Not because packages are bad — but because owning that piece of code might teach you something.

And if you're going to start building your own library of utilities, Snippet Ark is how I keep mine organized, searchable, and always ready to use. Your snippets are the best dependency you never had to install.

What's the one package you'd remove from your project right now? I'd genuinely love to know.