Vulkro vs Semgrep
Semgrep is the most widely deployed static analysis tool in the open-source SAST space. It's well-engineered, has thousands of community rules, and runs in pre-commit hooks across half the ecosystem. So why pick Vulkro?
The honest answer is that they target different points in the build / privacy / accuracy trade-space. This page makes the distinction concrete.
At a glance
| Vulkro | Semgrep CE | Semgrep AppSec Platform | |
|---|---|---|---|
| License | Closed-source detectors, per-term license, no auto-renewal | Open-source (LGPL 2.1) | SaaS, per-developer, auto-renews |
| Runs where | Your machine | Your machine | Your machine OR Semgrep cloud |
| Source code uploaded | Never | Not in CE | When using cloud features (configurable) |
| Cross-file analysis | Yes | No (single-file scope) | Yes (Pro engine) |
| Telemetry | None | Opt-out anonymous usage | Yes, in cloud tier |
| Rule authoring | YAML (regex or AST mode, P3.1) | YAML (code-like patterns) | Same as CE + cloud-managed packs |
| Custom-rule reuse | Semgrep YAML import shim (P3.2) | Native | Native |
| CVE / SCA matching | Local CVE bundle (OSV+NVD+KEV+EPSS) | Separate semgrep supply-chain tier | Cloud-side |
| OWASP API Top 10 coverage | All 10 + LLM 01/06 | Community rules; coverage varies | Same + curated packs |
Benchmark — Tier 1 corpus
Reproducible via bench/comparison/run.sh --tier1 --tools vulkro,semgrep from a checked-out Vulkro release tag.
The latest measured numbers are appended to CHANGELOG.public.md on every release, anchored to a
git describetag so the claims stay reproducible.
| vulkro | semgrep CE | |
|---|---|---|
| precision | leads | leads |
| recall | leads | varies |
| F1 | leads | varies |
(Numbers regenerate on every release; see the changelog for the locked figures matching this commit.)
The architectural distinction
The split between Vulkro and Semgrep CE is where the analysis runs and what data leaves the machine:
- Vulkro: detection engine + CVE bundle live on the same
machine that holds the source.
VULKRO_OFFLINE=1enforces this at the process boundary. The only network call isvulkro update(signed bundle fetch fromdist.vulkro.com), opt-out. - Semgrep CE: same posture in default mode. Source stays local. The CE binary doesn't phone home for findings, only for opt-out anonymous usage telemetry.
- Semgrep AppSec Platform: source can be uploaded to Semgrep's cloud for the cross-file Pro engine to run, the AI Assistant to triage, or the Supply Chain database to match against. Read Semgrep's terms before pointing the Pro engine at a repo with customer data.
The split between Vulkro and Semgrep AppSec Platform is
closed-source detectors with a public benchmark vs
SaaS-managed detectors with vendor-published claims. Vulkro
ships the benchmark harness (bench/comparison/) and the
ground-truth corpus (bench/comparison/groundtruth/); anyone can
reproduce the precision / recall numbers. Semgrep's curated
detection rules are managed in the cloud and not externally
verifiable to the same degree.
When to pick Semgrep CE
- Your team already runs Semgrep in CI and has invested in authored rules.
- Your detection profile is dominated by language-specific conventions (Python null-check patterns, JS async-handler idioms) where Semgrep's community rule pack has wide coverage.
- You're comfortable with single-file analysis as the default precision tier.
When to pick Vulkro
- Your data-handling policy or contract forbids source upload to any third party — including for "evaluation" or "optional cloud features" tiers.
- You want CVE / SCA coverage in the same scan as SAST (one binary, one report, one CI step).
- You need cross-file taint flow as a default (no separate Pro engine to enable).
- You want the OWASP API Top 10 + LLM Top 10 (LLM01 / LLM06) out of the box.
- You want a per-term license with no auto-renewal (Vulkro Pro is $19/month or $149/year; the term expires and the CLI keeps working — only the bundle and new detector packs stop).
Migration: bring your Semgrep rules to Vulkro
vulkro rules import-semgrep ./semgrep-rules.yaml translates a
strict subset of Semgrep YAML into Vulkro's CustomRule format.
Field-level translation:
id,message,languages,fix→ directseverity: INFO → low, WARNING → medium, ERROR → highmetadata.cwe→ vulkrocwepattern: best-effort regex translation ($IDENT→.+?,...→.*)
Compound shapes (pattern-either, pattern-not, patterns:
AND-composition) are skipped with a per-rule stderr warning
naming the unsupported feature. See P3.2 in the
CHANGELOG
for the full grammar.
Try both side by side
# In your project root:
vulkro scan . --format sarif > vulkro.sarif
semgrep --config p/owasp-top-ten --sarif --output semgrep.sarif
# Diff in your favourite SARIF viewer.
Both tools emit SARIF; GitHub Code Scanning ingests either format. The split-and-compare workflow is the fastest way to see whether Vulkro's defaults match your codebase before you commit to a license.
See also: Vulkro vs Bearer, Vulkro vs Snyk, Safety, CVE bundle changelog.