DEV Community

137Foundry
137Foundry

Posted on

How to Run a Lightweight Dependency Audit Before Anyone Asks You To

Dependency audits have a reputation for being tedious, multi-day projects that only happen right before a compliance deadline or a technical review. That reputation is mostly earned when a team waits years between audits and has to catch up on everything at once. Done on a regular cadence, the same process takes an afternoon and catches problems while they're still cheap to fix.

The difference between a painful audit and a routine one usually comes down to frequency rather than tooling. Teams that run this quarterly are working through a short, predictable list each time. Teams that run it once every few years are effectively doing archaeology on their own dependency tree, trying to reconstruct decisions nobody remembers making.

Here's a version you can actually run this week, without blocking anyone's sprint. It's built around six short steps, each one small enough to fit into a normal afternoon without derailing whatever else is on the roadmap.

Step 1: Generate a full dependency list with versions

Start with whatever your package manager gives you natively. For Node projects, npm list --all or the equivalent in your lockfile gives you direct and transitive dependencies. Python, Go, and Ruby projects all have similar built-in commands. The goal at this stage isn't analysis, it's just getting a complete, accurate list in one place, since most teams are surprised by how many transitive dependencies show up that nobody consciously chose.

organized server rack cabling in a small data closet
Photo by Kvistholt Photography on Unsplash

Save this list somewhere your team can find it again in three months, not just in a terminal scrollback that's gone by the next day. A plain text file committed alongside the code, or a dated export in whatever documentation tool you already use, is enough. The point isn't a fancy format, it's being able to compare this quarter's list against last quarter's without redoing the work from scratch.

Step 2: Check for known vulnerabilities

Run your package manager's built-in audit command first, since most modern ones ship with basic vulnerability scanning against public advisory databases. For a deeper pass, a dedicated tool like Snyk or a service that checks against the National Vulnerability Database directly will catch more than the built-in scanners, particularly for less common package ecosystems.

If your team hasn't done this before, expect the first run to feel alarming. That's normal, and it's exactly why doing it on a schedule matters more than doing it once, since the second and third runs will show a shrinking, more manageable list instead of the same overwhelming one every time.

Don't panic at the raw count. Most scans return a long list, and a meaningful chunk of it will be low-severity issues in dependencies-of-dependencies that aren't actually reachable from your code paths. Sort by severity and exploitability first, then work down.

A good rule of thumb: anything rated critical or high severity with a known, publicly available exploit gets addressed this week. Everything else goes into a tracked backlog with an owner, rather than either getting fixed in a panic or ignored entirely. Most teams only have the bandwidth for one of those two outcomes without a system in between.

Step 3: Check licenses, not just vulnerabilities

This step gets skipped constantly, and it's the one that causes the most surprise later. A dependency licensed under something copyleft, brought in years ago for a small utility, can turn into a real legal question if your product is ever acquired, resold, or offered as a white-label service. The Open Source Initiative maintains a clear reference for what different license families actually require, which is worth having open while you review the list.

Tools like FOSSA can automate this scan across your whole dependency tree if you'd rather not eyeball a spreadsheet manually.

Most permissive licenses, MIT, Apache 2.0, BSD, carry essentially no obligations beyond keeping the attribution notice intact. What you're actually hunting for is copyleft licenses that could require derivative code to be open sourced, which matters enormously if your product is closed source and barely at all if it isn't.

Step 4: Check your CI pipeline actually enforces what you think it does

While you're in here, it's worth a quick sanity check on whether your continuous integration setup actually blocks merges when tests fail, or whether that gate has quietly been bypassed somewhere. Teams under deadline pressure sometimes add an override without fully realizing it's become a habit rather than an exception.

This isn't strictly a dependency concern, but it tends to surface naturally during this kind of review, and it's exactly the sort of gap that's cheap to fix now and expensive to discover later during an incident or an outside review.

Step 5: Flag anything abandoned or years out of date

Cross-reference your dependency list against last-commit dates on each project's repository. A package that hasn't been touched in three or four years isn't automatically a problem, some tools are simply finished and stable, but it's worth a deliberate decision rather than an accidental one. Note which of your dependencies fall into this category and whether there's an actively maintained alternative worth planning a migration toward.

Pay particular attention to anything sitting at the center of your architecture rather than a peripheral utility. An abandoned formatting library is a minor inconvenience. An abandoned framework your entire application is built on is a multi-quarter migration project waiting to happen, and it's much easier to plan for early than to discover under pressure.

Step 6: Write down what you found, even briefly

The audit itself isn't the valuable part, the written record is. A short document, even a single page, listing what you checked, what you found, and what you decided to do about each finding turns a one-time scramble into something you can point to later. This is exactly the kind of artifact that makes a technical review go faster instead of slower, whether that review is an internal security check or something more formal.

Keep the write-up short on purpose. A one-page summary that someone will actually read and reference beats a fifteen-page report that gets filed away and forgotten. Include the date, what was checked, what was found, and the decision made about each finding, even if that decision was "acceptable risk, revisit next quarter."

137Foundry's engineering team has run this exact process for clients preparing for outside technical review, and it's covered in more depth, alongside the rest of what reviewers actually check, in this guide on preparing a codebase for technical due diligence.

Making it a habit instead of a one-off

The version of this that actually sticks is small and recurring, quarterly is usually enough, rather than a single heroic pass once every few years. Put it on the calendar next to whatever other recurring engineering hygiene tasks your team already does, and treat the write-up as non-negotiable even when the findings are boring. Boring findings, written down consistently, are exactly what you want to be able to show anyone who asks.

The teams that get the most value from this aren't the ones with the cleanest dependency trees. They're the ones who've made checking a routine part of how they work, so nothing sits unexamined long enough to become a real problem. Start with one afternoon this quarter, and the version six months from now will already be faster because most of the setup work is already done.

Top comments (0)