Safeguard
DevSecOps

snyk test and snyk code test: Command Guide with Examples

snyk test scans your dependencies; snyk code test runs SAST on your own source. Install, auth, flags, CI exit codes, and the gotchas between the two commands.

Karan Patel
Platform Engineer
7 min read

snyk test scans your open-source dependencies against Snyk's vulnerability database, while snyk code test performs static analysis (SAST) on the code you wrote yourself — two different engines, two different failure modes, and mixing them up is the most common source of "why did the scan miss this?" confusion. Both live in the same CLI binary and share auth, output flags, and exit-code conventions, so once the distinction is clear the rest is mechanical.

This guide covers installation, authentication, the flags that matter for each command, and the patterns for wiring both into CI without flaky builds.

Installing the CLI

Four supported routes; pick whichever matches your environment:

# npm (most common where Node is present)
npm install snyk -g

# Homebrew — note the tap; a plain snyk install via brew needs it first
brew tap snyk/tap
brew install snyk

# Scoop on Windows
scoop bucket add snyk https://github.com/snyk/scoop-snyk
scoop install snyk

# Standalone binary (CI images, no package manager)
curl -Lo ./snyk https://downloads.snyk.io/cli/stable/snyk-linux
chmod +x ./snyk && mv ./snyk /usr/local/bin/

The Homebrew detail trips people up: the formula lives in snyk/tap, so run the brew tap snyk/tap step or the install will not resolve. In Docker-based CI, prefer the standalone binary or the official snyk/snyk images over installing Node just to get npm.

Then authenticate. Interactively, snyk auth opens a browser flow; in CI, set the SNYK_TOKEN environment variable from a service account token instead — never bake tokens into images or scripts.

snyk auth            # local, browser-based
export SNYK_TOKEN=... # CI, from your secret store

snyk test: dependency scanning

Run from a project root, snyk test finds your manifest (package.json, pom.xml, go.mod, requirements.txt, and so on), resolves the dependency graph, and reports known vulnerabilities with upgrade paths:

snyk test                          # current project
snyk test --all-projects           # monorepo: walk subdirectories
snyk test --severity-threshold=high  # only fail on high/critical
snyk test --json > results.json    # machine-readable output
snyk test --fail-on=upgradable     # only fail when a fix exists

Points worth knowing before CI integration:

  • It tests the resolved graph, not the lockfile text. For Maven and Gradle it invokes the build tool to resolve dependencies, so the CLI needs a working build environment — a bare alpine container will produce different (worse) results than your real build image.
  • --all-projects changes exit-code semantics — any failing subproject fails the run, so a monorepo gate is only as calm as its noisiest package.
  • --fail-on=upgradable is the pragmatic gate: failing builds on vulnerabilities that have no released fix creates pressure with no outlet.
  • snyk test consumes an Open Source test from your plan quota on every invocation, which matters on the free tier's monthly caps.

The sibling command snyk monitor does not gate anything — it snapshots the dependency tree to the Snyk web UI so you get alerted when a new advisory affects an already-shipped version. test is the gate, monitor is the tripwire; production-grade pipelines run both.

snyk code test: static analysis on your source

snyk code test uploads your source (not just manifests) for SAST analysis and returns dataflow-style findings — SQL injection, XSS, path traversal, hardcoded secrets — with file and line references:

snyk code test
snyk code test --severity-threshold=high
snyk code test --sarif > code.sarif    # SARIF for GitHub code scanning
snyk code test --org=your-org-slug

Differences from snyk test that surprise people:

  • It must be enabled first. Snyk Code is toggled per organization in the web UI settings; a fresh org running snyk code test may get an error telling you to enable it rather than results.
  • Source leaves your machine. Analysis runs server-side, which is a data-governance conversation in some shops, not a technical one.
  • Severity thresholds behave the same, but the findings do not. SAST findings are probabilistic in a way database-backed dependency findings are not — a taint-flow finding may be a true positive that is unreachable in practice. Budget triage time accordingly, and read up on handling false positives and false negatives before wiring it as a hard PR gate.
  • --sarif output plugs into GitHub's code-scanning UI, which is often a better review surface than CI logs.

Language coverage differs between the two engines as well — a language Snyk Open Source supports is not automatically covered by Snyk Code (see the current gaps in our Snyk Code language matrix).

Exit codes and CI wiring

Both commands share exit-code conventions, and they are the API your pipeline actually consumes:

  • 0 — no issues at or above your threshold
  • 1 — vulnerabilities found (this is the "fail the build" signal)
  • 2 — CLI failure: bad flags, network trouble, unsupported project
  • 3 — no supported projects detected

The critical discipline: treat 2 and 3 differently from 1. A pipeline that fails identically on "vulnerability found" and "scanner broke" trains developers that red means retry; a pipeline that swallows all nonzero codes to stop the noise is a scanner you no longer have. Minimal honest wiring:

snyk test --severity-threshold=high
rc=$?
if [ "$rc" -eq 1 ]; then echo "vulns at/above threshold"; exit 1; fi
if [ "$rc" -ge 2 ]; then echo "scanner error, investigate"; exit "$rc"; fi

A workable rollout pattern: start with snyk test --severity-threshold=critical --fail-on=upgradable as a hard gate plus snyk code test --sarif as a non-blocking report; ratchet thresholds down as the backlog clears. Instant zero-tolerance gates on a legacy codebase produce exactly one outcome — the step gets commented out within a month.

Quota note for free-tier users: every CI invocation consumes tests from monthly caps (around 200 open source and 100 code tests). PR-triggered scans on an active repo exhaust that quickly, which is a pricing consideration, not a technical one — comparisons like Safeguard vs Snyk mostly turn on that metering model rather than on the CLI ergonomics, which are genuinely good.

Common failures and fixes

  • "Failed to get dependencies" on Maven/Gradle: the CLI shells out to your build tool. Ensure the CI step runs in the real build image with caches warm, and that mvn dependency:tree works standalone.
  • Monorepo scans time out: scope with --all-projects --detection-depth=2, or run per-package scans in parallel jobs instead of one mega-scan.
  • snyk code test returns nothing for a supported language: check the org-level Snyk Code toggle and confirm the files are not excluded by .snyk policy or --exclude globs.
  • Different results locally vs CI: usually a different resolved dependency graph (different JDK, Node version, or lockfile state), not scanner nondeterminism. Diff snyk test --print-deps output from both environments.

FAQ

What is the difference between snyk test and snyk code test?

snyk test checks your third-party dependencies against a vulnerability database (SCA). snyk code test statically analyzes your own source code for flaws like injection and XSS (SAST). They use different engines, different quotas, and find non-overlapping problems; a complete pipeline runs both.

How do I install the Snyk CLI with Homebrew?

brew tap snyk/tap followed by brew install snyk. The tap step is required because the formula is published in Snyk's own tap, not homebrew-core. Alternatives: npm install snyk -g, Scoop on Windows, or standalone binaries for CI.

Why does snyk test pass locally but fail in CI?

Almost always a different resolved dependency graph — different tool versions, missing build environment, or stale lockfile — rather than flaky scanning. Compare snyk test --print-deps in both environments to see the divergence.

Can I use snyk code test without a paid plan?

Yes, within the free plan's monthly Snyk Code test quota (around 100 tests per month as of 2026), after enabling Snyk Code in your organization settings. Active CI usage will exhaust that quota; paid tiers remove the caps.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.