Use dependencies.yml if your package specs have no Jinja and you work with cross-project references. Keep packages.yml if you render values such as environment variables into package specs, or use private packages. The deciding feature is Jinja: packages.yml renders it, dependencies.yml deliberately does not.
What each file is for
The dbt packages documentation draws the line like this.
- dependencies.yml can hold both package and project dependencies. Use it for cross-project references in a dbt Mesh setup, or to combine them with Hub packages.
- packages.yml is for downloading packages into your project. The docs say it does not contribute to the Mesh workflow. It supports Jinja rendering "for historical reasons", which lets you insert values like environment variables.
Private packages are not supported in dependencies.yml, because it intentionally does not support Jinja rendering or conditional configuration. If your specs do not use Jinja, you can rename the file. If they do, keep the packages.yml name.
Why Jinja matters for review
A static file can be read and reasoned about by a person or a scanner. A file with Jinja can produce different package lists depending on the environment: one thing in development, another in production, depending on variables and conditions.
That is flexibility with a price. A reviewer who reads the file in a pull request sees a template, not the resolved list. The lock file helps here. The docs say dbt writes a lock file that records exact resolved versions including commit hashes, and that as long as the packages file has not changed, the same versions are installed even if newer ones appear.
A comparison
| Question | dependencies.yml | packages.yml |
|---|---|---|
| Jinja rendering | No | Yes |
| Private packages | Not supported | Supported |
| Mesh cross-project refs | Supported | No |
| Reviewable as static text | Yes | Only if you avoid Jinja |
Practical advice
- If you can use plain, static specs, do. Fewer moving parts means easier review.
- Pin every Git package. The docs say unpinned Git packages raise a warning, and silencing it with the warn setting is not recommended. Use a branch, tag or full 40 character commit hash.
- Commit the lock file, and update it on purpose with the deps upgrade option.
- If you use Jinja, limit it to injecting a token or switching a path. Do not use it to change which package is installed per environment.
- Check the resolved list in CI. Print the lock file or export the inventory so a reviewer sees what actually installs.
- Remember Hub packages are not certified. The docs say dbt Labs does not certify the integrity, operability, effectiveness or security of any packages.
Do not skip the review
Neither file makes a package safe. Package code can run SQL against your warehouse. A review before the first install, and for each upgrade, is the control. See the earlier posts on reviewing a package before running the install command and on pinning with the lock file.
Safeguard's SBOM and dependency scanning can read either file and the lock file to list what a dbt project installs. The free scan at https://gold.safeguard.sh/scan is a quick way to try it.
Quick check
Can I just rename packages.yml to dependencies.yml?
Only if your specs use no Jinja. Private packages also need packages.yml.
Which one is safer?
Neither is by itself. A static file is easier to review, and a pinned, locked package list matters more than the file name.
Sources
Last reviewed: 19 October 2026.