A package registry is a central, networked service that stores published software packages and hands them out to build tools and package managers by name and version. When a developer declares that a project depends on a library, the package manager contacts the registry, asks for that exact package, and downloads it. The registry is the backbone that makes one-line dependency declarations possible.
The npm documentation defines the public npm registry plainly: it is “a database of JavaScript packages, each comprised of software and metadata” (https://docs.npmjs.com/about-the-public-npm-registry). That phrasing captures the two halves a registry must store: the package itself (the code) and the metadata that describes it (its name, version, declared dependencies, and how to fetch it).
Every major language ecosystem has one. The Java world resolves dependencies from Maven Central, which the Apache Maven documentation describes as a place where users get “dependencies for their own builds” and projects publish “releases to be added to the central repository” (https://maven.apache.org/repository/index.html). Python has PyPI, Rust has crates.io, .NET has the NuGet Gallery, and Ruby has RubyGems. The contract is the same in each: publish named, versioned packages, and serve them reliably.
Because so much software is pulled from a handful of registries, they are also a high-value attack surface. A single malicious or compromised package on a popular registry can flow automatically into thousands of downstream builds. That dual nature, indispensable infrastructure and concentrated risk, is why registries sit at the center of modern dependency management and of software supply chain security.