Reproducible builds mean the exact same source, built the same way, produces a byte-for-byte identical output every time, and achieving that in a project with many third-party dependencies means eliminating every source of non-determinism the build process and its dependencies could introduce, not just pinning versions.
The techniques, and what each closes
Dependency pinning and lockfiles: commit the exact resolved version of every direct and transitive dependency, not a semver range, so two builds run at different times against the same lockfile resolve to identical dependency versions rather than picking up whatever's newest at build time.
Checksum verification: verify that every downloaded dependency matches a known-good cryptographic hash before it's used in the build, catching a case where a package registry serves different bytes for the same declared version (whether due to a compromise, a registry bug, or a package being silently republished under the same version number).
Vendoring: copy the exact dependency source or binaries into your own repository or build cache rather than fetching them fresh from an external registry on every build; this removes the external registry as a point of non-determinism (an outage, a rate limit, a removed package) entirely, at the cost of a larger repository and the responsibility of updating vendored copies yourself.
Hermetic build environments: run the build inside an environment with no ambient, unpinned inputs (no system-installed compiler version that could differ between machines, no network access during the build itself beyond what's explicitly declared and pinned), so the build's output depends only on what's explicitly declared as an input, not on whatever happens to be installed on the machine running it.
Content-addressable caches: cache build outputs keyed by the hash of their inputs, so an unchanged input always resolves to the same cached output rather than a potentially-different rebuild.
Signed artifacts: once you've achieved a reproducible build, signing the resulting artifact lets a downstream consumer verify not just who built it, but that a third party could independently reproduce the exact same output from the same declared source.
Trade-offs in developer experience versus strict reproducibility
Each of these techniques trades some developer convenience for reproducibility: pinning exact versions means a developer can't casually pick up a dependency update without an explicit action; vendoring adds repository size and a manual update step; hermetic environments mean a developer can't rely on whatever's already installed on their laptop and has to use the same pinned toolchain everyone else does. Full hermetic reproducibility (matching the rigor of, say, a Bazel remote-execution setup) is a substantial engineering investment appropriate for a security-critical or supply-chain-sensitive project; a smaller project may reasonably stop at lockfile pinning and checksum verification, accepting a lower but still meaningfully improved level of reproducibility without the full hermetic-environment investment.
Trade-offs
The honest trade-off across all of these is between reproducibility STRENGTH and developer velocity: each additional technique closes a real gap the previous ones leave open, but each also adds friction to a developer's everyday workflow, so the right stopping point depends on how much supply-chain assurance the specific project actually needs, not a universal 'do all of it' answer.