Scan both, because they answer different questions. The source repository and lockfile show what you chose and what the build installed. The built output shows what visitors actually receive, including bundled libraries and external script references. If you must pick one first, start with the lockfile.
What each one sees
| Approach | Sees | Misses |
|---|---|---|
| Manifest alone | Direct packages and version ranges | Exact versions, transitive packages |
| Lockfile | Exact resolved versions, transitive packages | Whether a package shipped, runtime script tags |
| Source code analysis | Unsafe patterns in your own code and components | Third-party code you did not write |
| Built output | Bundled libraries, version banners, external hostnames | Build-time tooling, server functions |
| Live site crawl | What a browser loads right now, headers, scripts from other hosts | Anything behind a login, code paths not triggered |
No row is complete. Together they cover most of what matters.
Why the lockfile first
A lockfile records the exact versions the build resolved. That is the data advisories match against. It also includes build tooling, which can be the entry point for a pipeline compromise. Scanning from the lockfile is fast, needs no build, and fits in a pull request check.
Why you still need the output
Source-level scans cannot see everything that ends up on the page.
- Tag-injected scripts. Tags added through a tag manager or inserted by a template are not in your package list. See your tag manager is a second deployment pipeline.
- Vendored files. A library copied into a static folder has no manifest entry. Banner comments in the file may reveal its version.
- Build surprises. A bundler may include a different version than the one you expected if two versions exist in the tree.
- Headers and configuration. A request to the deployed site shows what the CDN actually sends.
A practical order
- Scan the lockfile on every pull request.
- Run source code analysis on your own components and functions.
- After deploy, crawl the live site and list external hostnames and script URLs. Compare with the previous crawl and flag new ones.
- Check headers with a few curl requests, or a scheduled job.
- Rescan stored results on a schedule, since advisories arrive later.
Reading the results together
If the lockfile scan reports a vulnerable package and the output scan shows no trace of it, you likely have a package used at build time. If the output shows a library the lockfile does not list, you have a vendored or injected file that nobody is tracking. That second case is the one to chase, because no automatic update will ever fix it.
Try it yourself
In the dependency inventory demo, look at how each component carries a version and a source. Think about which of your files would not appear in such a list.
Click through it at your own pace, or open it full screen.
Where Safeguard fits
Safeguard generates SBOMs and scans dependencies from your repository, and its asset discovery helps account for what you run. Try the free scan at gold.safeguard.sh/scan.
Quick check
Is scanning minified bundles reliable?
It can find version banners and known file signatures, but results are less certain than lockfile data. Treat them as leads.
Does a live crawl replace a code scan?
No. It sees the delivered result, not the cause. Use it to catch what the repository does not describe.
Last reviewed: 19 October 2026.