Dependency resolution is the task a package manager performs to pick a single set of versions that satisfies every constraint in a project at once. You ask for a few libraries; each of those libraries in turn requires other libraries, and each requirement is often expressed as a range of acceptable versions rather than a single one. The resolver must find one version of each package such that all of those overlapping ranges are satisfied simultaneously.
The official documentation of several ecosystems describes this directly. The RubyGems dependency management guide notes that gems “usually declare a range of versions for their dependencies,” and that when you install, the tool must find all required gems meeting your specifications, including the transitive ones. Composer’s versions documentation explains that it “finds the highest version that matches all version constraints in your project.” Cargo’s guide describes how it resolves dependencies and then records the exact chosen versions in a lockfile.
This is harder than it looks. When two of your dependencies demand incompatible versions of a shared third library, there may be no valid solution at all, and the resolver reports a version conflict. Searching for a satisfying combination across many packages with overlapping constraints is, in the general case, a computationally hard problem; some modern resolvers treat it as a constraint-satisfaction or SAT problem internally.
Dependency resolution matters because it is the invisible engine behind everyday commands like bundle install or composer update, and it is the source of the conflicts that frustrate developers. Understanding that the manager is solving a constraint problem explains both why installs can fail with seemingly cryptic version errors and why lockfiles, which record an already-solved answer, make later installs fast and reproducible.