The "Leftpad" Problem
In March 2016, a developer named Azer Koçulu unpublished 273 npm packages from the public npm registry in a dispute over a package name. One of those packages, left-pad, was a 11-line utility that padded strings. It was a dependency of Babel, which was a dependency of React, which was a dependency of thousands of production applications. Within hours, builds were failing globally. The internet broke because of an 11-line file.
This incident crystallized three reasons why you should never let your build servers pull directly from public package registries:
- Availability: Public registries go down, packages get unpublished, and CDNs have outages. Your build pipeline should not depend on the public internet being healthy.
- Security: A malicious actor can publish a typosquatted package (
lodahsinstead oflodash) or, in supply chain attacks, compromise a legitimate package's publish credentials and push malware. Without a scanning layer, that malware goes straight into your build. - Speed and Cost: Downloading 500MB of
node_modulesfrom a CDN in another continent on every CI run is slow and incurs egress costs. A local cache is faster and cheaper.
How Proxy Caching Works
Tools like JFrog Artifactory and Sonatype Nexus act as a proxy cache — an intermediary that sits between your developers and the public internet.
The flow works like this:
- A developer's machine or CI runner is configured to point at the internal Artifactory URL instead of
registry.npmjs.org. - The developer runs
npm install react. - Artifactory checks its local cache.
- Cache hit: Returns the package immediately. Fast, no internet required.
- Cache miss: Downloads the package from the public registry, runs a vulnerability scan (e.g., against the OSS Index or Xray database), caches it locally, and returns it to the developer.
- Every subsequent request for that package version hits the cache.
Virtual and Local Repositories
Artifactory and Nexus introduce a three-repository model that's worth understanding:
- Remote Repository: The proxy to a specific upstream (e.g.,
npmjs.com,pypi.org,hub.docker.com). Artifactory fetches and caches from here. - Local Repository: Where your organization's own artifacts are published (e.g., your internal npm packages, your built Docker images).
- Virtual Repository: A single URL that aggregates one or more remote and local repositories. Developers point at the virtual URL and never need to know whether a package is internal or cached from upstream.
This model means a developer runs npm install against one URL and gets both internal packages and cached public packages transparently.
A common interview question is: "What's the difference between a proxy repository and a local repository in Artifactory?" The answer: a proxy repository caches artifacts from an external upstream (like npmjs.com), while a local repository stores artifacts your team has built and published internally. A virtual repository aggregates both behind a single URL. Interviewers ask this to verify you've actually operated one of these systems, not just read about it.