Skip to main content

Building PkgPulse: How I Compare npm Packages with Real Data

·PkgPulse Team
toolsnpmopen-sourcejavascriptweb-development

The Problem Every Developer Ignores Until It's Too Late

You're starting a new project. You need a date library. So you Google "best JavaScript date library" and get a blog post from 2022 recommending Moment.js — a package that's been deprecated since 2020 and adds 72kB to your bundle.

Every developer faces "which package should I use?" decisions weekly. The existing tools each solve one piece of the puzzle. npmtrends shows download counts. Bundlephobia shows bundle size. Snyk shows vulnerabilities. But no single tool answers the real question: is this package actually healthy? Maintenance activity, popularity trends, bundle impact, and security status — you had to check four different sites to figure that out.

I got tired of the tab-switching ritual. Check npm for the last publish date. Check downloads on npmtrends. Check bundle size on Bundlephobia. Check Snyk for CVEs. Four tabs, four UIs, and I still had to synthesize the answer in my head.

So I built an npm package comparison tool that does it all in one search. That's PkgPulse.

What PkgPulse Actually Does

PkgPulse is a side-by-side npm package comparison tool that answers "which package should I use?" with real data. The core concept: Health Scores.

Every package gets a score from 0 to 100 based on five weighted dimensions:

DimensionWeightWhat It Measures
Maintenance30%Days since last publish, open issues ratio
Quality25%TypeScript support, type definitions
Popularity20%Weekly download volume (logarithmic scale)
Security15%Known vulnerabilities (critical → none)
Stability10%Breaking change frequency

Search for any two packages on pkgpulse.com and you get a comparison page with health scores, 12-week download trend charts, gzipped bundle sizes, and security status — all in one view. No more tab-switching to compare npm packages.

I also built over 160 pre-built comparison pages covering every common "X vs Y" decision: React vs Vue, Express vs Fastify, Jest vs Vitest, Prisma vs Drizzle, and more across 30+ categories.

On top of the comparison tool, I publish data-driven blog articles analyzing the most popular matchups — complete with code examples, migration guides, and decision frameworks.

The Tech Stack

Here's what I chose and why:

LayerTechnologyWhy
FrameworkNext.js 16 + React 19App Router, ISR for dynamic pages at scale
LanguageTypeScript (strict)Type safety across the entire codebase
StylingTailwind CSS 4Dark mode, responsive, fast iteration
Data Fetching@tanstack/react-queryClient-side caching + background refetches
ChartsRechartsDownload trend visualizations
BlogMDX + next-mdx-remoteRich content with embedded components
Markdownremark-gfm + rehype-slug + rehype-highlightTables, heading links, syntax highlighting
AnalyticsVercel Analytics + Speed InsightsPage views, Core Web Vitals monitoring
HostingVercelEdge network, automatic ISR, zero-config deploys
IconsLucide ReactConsistent, lightweight icon library

The data pipeline hits three APIs in parallel for every package lookup:

const [npm, downloads, bundleSize] = await Promise.all([
  fetchJson(`/api/npm/${packageName}`),
  fetchJson(`/api/downloads/${packageName}`),
  fetchJson(`/api/bundle-size/${packageName}`),
]);

Three independent requests, parallelized — not sequential. For a two-package comparison, that's six API calls completing in roughly the time of one.

This was one of the first architecture decisions I got right. The original version fetched sequentially — npm data, then downloads, then bundle size — and comparison pages took 3-4 seconds to load. Parallelizing cut that to under a second.

Each API route also has its own caching strategy tuned to how fast the data changes:

// Package metadata changes rarely — 1 hour cache
next: { revalidate: 3600 }

// Downloads and bundle sizes — 24 hour cache
next: { revalidate: 86400 }

Bundle size data was the trickiest to get right. I built a fallback chain: try Bundlephobia first (the most accurate source), and if it's down or doesn't have the package, fall back to npm registry's unpacked size with a 30% gzip compression estimate:

// Fallback: estimate from npm registry data
const unpackedSize = versionData?.dist?.unpackedSize || 0;
const estimatedGzip = Math.round(unpackedSize * 0.3);

Is a 30% ratio perfectly accurate? No. But it's a reasonable heuristic that keeps the page functional even when external services are unreliable. Ship the good-enough answer instead of showing a loading spinner forever.

Interesting Design Decisions

Health Scores instead of just downloads. Downloads don't equal quality. A package can have millions of weekly downloads and still be unmaintained, riddled with vulnerabilities, or shipping 200kB of unminified JavaScript. The health score forces a more nuanced comparison. I gave Maintenance 30% of the weight — because a package that hasn't been updated in two years is a liability, no matter how popular it is.

Getting the weights right took iteration. My first version weighted Popularity at 40%, which meant massively-downloaded-but-abandoned packages scored well. That defeated the whole purpose. I flipped it: Maintenance 30%, Quality 25%, and Popularity down to 20%. Now the score actually reflects what I'd care about when picking a dependency.

Two-package comparisons, not data dumps. Most package decisions are binary: "Should I use X or Y?" I optimized for that specific decision. You search two packages, you see them side-by-side, you make a call. PkgPulse isn't trying to be a package registry — npm already does that. It's the tool you reach for when you're stuck between two options.

I briefly experimented with three-way comparisons (React vs Vue vs Svelte). The UI got cluttered fast, and the data showed most users were searching exactly two packages. I killed the feature and focused on making two-package comparisons excellent.

Over 160 pre-built comparison pages for SEO. Every "[X] vs [Y]" query is a potential Google search. "zustand vs redux" gets thousands of monthly searches. By pre-building these pages with Incremental Static Regeneration, they load fast, stay indexable, and always show fresh data. The URLs are canonicalized — react-vs-vue and vue-vs-react both resolve to the same alphabetically-sorted page:

export function getComparisonSlug(packages: string[]): string {
  return [...packages].sort().join('-vs-');
}

AI-first SEO strategy. The robots.txt explicitly allows AI crawlers — GPTBot, ClaudeBot, PerplexityBot, Google-Extended. Every comparison page ships JSON-LD structured data: WebPage, BreadcrumbList, FAQPage, and Dataset schemas. When someone asks an AI "should I use React or Vue?", I want PkgPulse data in the answer. This is a first-mover bet that AI-driven search will matter as much as traditional SEO within a year.

Curated alternatives, not algorithmic. I maintain a hand-curated graph of 500+ packages and their alternatives. Search for React and you'll see suggestions for Vue, Angular, Svelte, Solid, and Preact — not some ML model's best guess. This is more work to maintain, but accuracy matters more than automation when developers are making dependency decisions.

What's Next

I'm adding new comparisons every week based on what developers actually search for. The current 160+ pages cover the biggest decisions, but the npm ecosystem has thousands of "X vs Y" moments.

What's on the roadmap:

  • Individual package pages — full health score breakdowns for any single package, not just comparisons
  • Historical health tracking — see how a package's maintenance and security has trended over months
  • Migration guides — when the data says "switch," I want to show you how
  • API access — so developers can pull PkgPulse health scores into their own CI pipelines or dashboards

If you want to compare npm packages without juggling four browser tabs, give it a try at pkgpulse.com — free, no signup required.


FAQ

What is PkgPulse?

PkgPulse is a free npm package comparison tool that shows health scores, bundle sizes, download trends, and security data side-by-side for any two packages.

How is the Health Score calculated?

The health score is a weighted average of five dimensions: Maintenance (30%), Quality (25%), Popularity (20%), Security (15%), and Stability (10%). Each dimension scores 0–100 based on real npm registry and vulnerability data.

How many comparisons does PkgPulse have?

PkgPulse has over 160 pre-built comparison pages covering 30+ categories — from frontend frameworks to ORMs to animation libraries. You can also compare any two npm packages by searching directly on pkgpulse.com.

Is PkgPulse free?

Yes. PkgPulse is completely free with no signup required. Search, compare, and make better dependency decisions.

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.