Debian 319 's tooling has two layers (7). dpkg installs one .deb file and records every file it owns, but never downloads or resolves anything. apt reads the repositories listed in /etc/apt/sources.list.d/, works out the dependency graph and calls dpkg in the right order. Try it in a throwaway Ubuntu 26.04 225 container.

docker run --rm --name l1-apt ubuntu:26.04 bash -c '
apt-get update -qq
apt-get install -y --no-install-recommends jq 2>&1 | grep -E "^(Setting up|Unpacking)"
dpkg -S /usr/bin/jq
apt-cache depends jq'Unpacking libonig5:amd64 (6.9.10-1build1) ... Unpacking libjq1:amd64 (1.8.1-4ubuntu2) ... Unpacking jq (1.8.1-4ubuntu2) ... Setting up libonig5:amd64 (6.9.10-1build1) ... Setting up libjq1:amd64 (1.8.1-4ubuntu2) ... Setting up jq (1.8.1-4ubuntu2) ... jq: /usr/bin/jq jq Depends: libjq1 Depends: libc6 Depends: libonig5
apt-get update refreshes the indexes (like fetching packuments); the install then pulls jq 133,477 and the two libraries it depends on, each a separate package shared system-wide. dpkg -S answers the question npm 2,036 cannot: which package owns this file. In scripts use apt-get, whose output format is stable; the friendlier apt command warns that its interface may change.
A machine can list several repositories that offer the same package, and apt then picks by pin priority before version. This book's host shows why Node.js 2,131 came from NodeSource rather than Ubuntu (Kinds of Package Managers).
apt-cache policy nodejs | sed -n '1,6p;/ubuntu1 /,$p'
cat /etc/apt/preferences.d/nodejsnodejs:
Installed: 24.21.0-1nodesource1
Candidate: 24.21.0-1nodesource1
Version table:
*** 24.21.0-1nodesource1 600
500 https://deb.nodesource.com/node_24.x nodistro/main amd64 Packages
22.22.1+dfsg+~cs22.19.15-1ubuntu1 500
500 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Packages
Package: nodejs
Pin: origin deb.nodesource.com
Pin-Priority: 600Every NodeSource version has priority 600, set by the preferences file NodeSource's setup script installed, against 500 for Ubuntu's own archive, so apt upgrade never swaps in Ubuntu's older Node.js 22 build. The same file format lets you hold a package at a version (Pin: version 24.21.*) when an upgrade must wait.