惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

www.infosecurity-magazine.com
www.infosecurity-magazine.com
D
DataBreaches.Net
T
Tailwind CSS Blog
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
F
Full Disclosure
V2EX - 技术
V2EX - 技术
N
News and Events Feed by Topic
Help Net Security
Help Net Security
L
LangChain Blog
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
B
Blog RSS Feed
N
Netflix TechBlog - Medium
N
News | PayPal Newsroom
TaoSecurity Blog
TaoSecurity Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Vulnerabilities – Threatpost
B
Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园_首页
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AI
AI
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyberwarzone
Cyberwarzone
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
G
GRAHAM CLULEY
Vercel News
Vercel News
罗磊的独立博客
MyScale Blog
MyScale Blog
Last Week in AI
Last Week in AI
博客园 - 司徒正美
C
CERT Recently Published Vulnerability Notes
GbyAI
GbyAI
Scott Helme
Scott Helme
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
A
About on SuperTechFans
P
Privacy International News Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
npm Dependencies: How to Evaluate a Library Before Shipping It to Production
Juan Torchia · 2026-06-22 · via DEV Community

npm Dependencies: How to Evaluate a Library Before Shipping It to Production

Back in 2005, when I was 16 and managing the network at a cyber café, I learned something no manual ever taught me: every cable you plugged in was debt. If the vendor for that cable disappeared or changed the connector, the problem was yours. Not the vendor's, not the customer's. Yours. Today, when I look at a package.json with 180 direct dependencies in a TypeScript project, I think exactly the same thing. Every entry in that file is a cable someone is going to have to maintain. And in most cases, that someone is you.

My take is direct: adding an npm dependency isn't just installing code — it's assuming its maintenance, its CVE history, its transitive dependencies, and the exit cost when the library gets abandoned. The question isn't "does it work?" The question is "what happens when it stops working in six months?"


Why Evaluating npm Dependencies Is a Maintenance Decision, Not Just a Security One

The official npm documentation defines a package as "a file or directory described by a package.json" (npm docs). That's all npm guarantees as a platform: that the file exists and has metadata. Nothing about whether the author is still active, whether it has tests, whether the types are correct, or whether you'll be able to upgrade in two years without breaking half the system.

What the official docs don't say — and where people get burned — is that a published package can freeze in time. The author might not have bandwidth, might abandon the project, or might simply never hear about a relevant CVE. And at that point, the debt is yours.

There are three dimensions that matter before installing anything in a TypeScript project with pnpm:

  1. Active maintenance: When was the last commit? Are there PRs that have gone unanswered for months? Any releases in the past year?
  2. Attack surface and types: Does the package ship its own types (@types/) or generate them? How many transitive dependencies does it drag in?
  3. Exit cost: If you need to rip it out tomorrow, how much of your own code changes?

How to Audit a Dependency Before pnpm add

The usual recipe is: search on npm, check if it has GitHub stars, install it, done. The problem is that measures popularity, not quality or longevity. Popularity and active maintenance are not the same thing.

Here's the process I use, step by step and fully reproducible:

1. Check the Real State of the Repository

Before installing, open the repo on GitHub and look at:

  • Last commit on main: if it's been more than 12 months with no activity and it's not a stable utility library (like lodash), that's a signal.
  • Open issues: Are there bugs sitting unanswered for months? CVEs mentioned but not patched?
  • CHANGELOG or releases: a serious project has a version history. If it doesn't, the risk surface goes up.

2. Analyze Transitive Dependencies with pnpm why

# Install in an isolated test project
pnpm add <package-name>

# See what it brought along
pnpm why <package-name>

# Or a full dependency tree
pnpm list --depth=3

A dependency that looks small can drag in 40 transitive packages. That's not automatically bad — but if two of those 40 have active CVEs, the problem is yours even if your own code never calls them directly.

3. Run a Security Audit From the Start

# Basic audit with npm (works on pnpm projects too)
npm audit

# To see only critical and high vulnerabilities
npm audit --audit-level=high

# If you want the JSON to process it
npm audit --json | jq '.vulnerabilities | to_entries[] | select(.value.severity == "critical")'

npm audit uses the npm Advisory Database to cross-reference installed versions against known CVEs. It's not infallible — there are vulnerabilities that don't have an advisory yet — but it's the minimum reasonable floor before committing to a dependency.

4. Verify TypeScript Types

In a TypeScript project, a dependency without types is guaranteed friction. Check:

# Does the package ship its own types?
cat node_modules/<package>/package.json | grep '"types"'

# Are @types/ available?
npm info @types/<package>

If the package doesn't ship its own types and the @types/ are community-maintained (not by the original author), you have two separate sources of drift. When the package updates and @types/ doesn't, the compiler fails in ways that aren't obvious.

5. Evaluate Exit Cost With Your Own Interface

This is the step that gets skipped the most. The question isn't just "does it work today?" but "how much code do I change if I rip it out tomorrow?"

// Pattern that reduces exit cost:
// Wrap the dependency behind your own interface

// ❌ Using the dependency directly throughout the codebase
import { parse } from 'some-date-lib'
const date = parse('2025-01-15')

// ✅ Abstracting behind your own module
// lib/dates.ts
import { parse as _parse } from 'some-date-lib'

export function parseDate(input: string): Date {
  return _parse(input) // single entry point
}

If the library is spread across 40 different files with no abstraction, removing it costs a major refactor. If it lives in one module, removing it costs an internal implementation swap.


The Most Common Mistakes When Evaluating npm Dependencies

Mistake 1: Confusing Weekly Downloads With Stability

npm download numbers include automatic mirrors, CIs, and pipelines. A library with 2M weekly downloads can have a maintainer who hasn't merged a PR in a year. Downloads are a lagging indicator of past popularity, not a guarantee of future support.

Mistake 2: Ignoring devDependencies in Projects With Build Steps

If a vulnerable devDependency is involved in the build (babel, webpack, esbuild, tsx), the code it generates can be compromised. The devDependencies field in package.json separates intent, not risk. If it goes through the compiler, it matters.

Mistake 3: Not Looking at peerDependencies

# Check what versions of React/Node the lib expects
npm info <package> peerDependencies

A library that asks for React 17 as a peer in a React 19 project might work — or it might produce silent bugs from duplicate context. Peer conflicts are one of the most common hidden costs in stack upgrades.

Mistake 4: Assuming a Small Package Is Safe

Attack surface isn't proportional to size. The event-stream incident in 2018 showed that a small utility package, transferred to a new maintainer, can become an attack vector. Small doesn't mean harmless. (Source: npm blog on the incident)

This kind of risk connects directly to what I wrote about OAuth Scope Creep: attack surface accumulates at the edges, not the center.


Decision Matrix: Do I Add This Dependency or Not?

Criterion Green (add it) Yellow (evaluate further) Red (avoid or wrap)
Last release < 6 months 6–18 months > 18 months with no activity
TypeScript types Bundled in the package Active @types/ aligned with the package No types or outdated @types/
Active CVEs None Low severity, no public exploit Critical or high with no patch
Transitive deps < 10 10–40 > 40 or deps with CVEs
Exit cost Easy to wrap Moderate coupling Invasive across multiple modules
Active maintainer Responds to issues/PRs Slow but responds No visible activity

If a dependency lands in "Red" on more than two criteria, the right question is: do I actually need this abstraction, or can I implement the specific logic I need in 50 lines of my own code?

When working on projects with pnpm workspaces — like I described in the post about pnpm workspaces and CI on Railway — this evaluation matters twice as much: a problematic dependency in a shared package of the monorepo gets inherited by every app in the workspace.


What This Checklist Can't Guarantee

Being honest about the limits:

  • It doesn't predict future abandonment: a library with recent releases can get abandoned tomorrow. The checklist measures current state, not future state.
  • npm audit doesn't cover all vectors: business logic vulnerabilities, sophisticated supply chain attacks, and unreported CVEs don't show up in a standard audit. It's the floor, not the ceiling.
  • The real exit cost only gets measured in practice: estimating the cost of removing a dependency is a heuristic. Until you actually do it, it's a projection. If the project already has the dependency deeply integrated, the retrospective evaluation is more expensive than the prospective one.
  • GitHub metrics are indicators, not proof: an archived repository can be stable because it reached feature-complete. A repo with tons of commits can be unstable due to constant refactoring. Context matters.

FAQ: Evaluating npm Dependencies in TypeScript Projects

How many direct dependencies is "too many" in a TypeScript project?

There's no universal number. What is a warning sign is having more than 50–60 direct dependencies without having actively evaluated which ones could be replaced by your own implementations. The criterion isn't the count — it's whether every entry in dependencies has a clear reason that can't be solved in fewer than 100 lines of your own code.

Does pnpm have security advantages over npm or yarn for this kind of audit?

pnpm has a different storage model (content-addressable store) that avoids duplication and makes the dependency tree more predictable. But for CVE audits, npm audit is still the standard tool and works with any lockfile. pnpm's advantage in this context is more about tree predictability than intrinsic security.

What do I do if a dependency has a CVE but no fix is available?

First, evaluate whether the CVE applies to how you're using it. Many CVEs have specific exploitation conditions that may not apply to your context. If it does apply, look for a fork with the fix, replace the dependency, or implement the minimum necessary functionality yourself. Keeping the vulnerable dependency and "noting it for later" is the most comfortable path and the most expensive one in the medium term.

Does it make sense to evaluate devDependencies with the same rigor?

Less rigor, but not zero. Build tools, linters, and compilers that go through the CI pipeline deserve a basic review. A devDependency that's only used on a local machine has less urgency than one that participates in generating the artifact going to production.

How do I evaluate a dependency when it has no visible public repository?

If an npm package doesn't have a public repository linked and has more than a couple of months of existence, the default criterion is don't install it in a serious project. The absence of a public source doesn't imply malice, but it eliminates the possibility of a code audit. Without visible source, the analysis is limited to what the package declares in its package.json — which is incomplete information.

How does this affect maintaining a monorepo with multiple apps?

A problematic dependency in a shared/ package of the monorepo propagates automatically to all consumers. That makes upfront evaluation more important, not less. The cost of a CVE or a breaking change in a shared dependency multiplies by the number of apps in the workspace. It's worth spending more time on shared package dependencies than on ones specific to a single app.


My Take and the Next Concrete Step

Adding an npm dependency is a technical decision with consequences that extend far beyond the current sprint. I'm not saying you should avoid libraries — that would be absurd in an ecosystem where composition is the model. I'm saying the upfront evaluation costs half an hour and can prevent weeks of maintenance debt.

What I don't buy is the idea that a package's popularity is sufficient evidence to install it without further analysis. GitHub stars don't pay the cost of a migration when the library goes unsupported.

What I do buy: implementing your own logic when the dependency alternative drags in 30 transitives, has no types, or has a maintainer who hasn't responded in a year. In those cases, 80 well-tested lines of your own code are a more honest investment than delegating to a package you can't control.

The next concrete step: open the package.json of the most active project you're currently working on. Pick the five dependencies you know the least about. Run pnpm why <package> on each one and look at the repository on GitHub. In at least one of them, you'll find something that deserves a conversation about whether it's still worth keeping.


Original sources:


This article was originally published on juanchi.dev