# cve-lite-cli: an OWASP scanner that prints the command to run

> cve-lite-cli is an OWASP Lab Project that scans JavaScript and TypeScript lockfiles for known vulnerabilities using OSV data, and its pitch is remediation rather than reporting: it prints the command to run. Everything runs on your machine, with no account and no API key, and the package supports npm, pnpm, Yarn and Bun.

**OWASP/cve-lite-cli** — Fast, developer-friendly JS/TS dependency vulnerability scanner with local lockfile scanning, OSV matching, direct vs transitive visibility, --fix, JSON output, and practical remediation guidance.

- Repository: https://github.com/OWASP/cve-lite-cli
- Website: https://owasp.github.io/cve-lite-cli/
- Stars: 773 · Forks: 176
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/owasp-cve-lite-cli

## The one line the README leads with

The README opens with a sentence that is also the project's pitch: most tools tell you what's wrong, and CVE Lite CLI tells you what to run.

That framing explains the feature list, which is unusual for a scanner. Alongside local lockfile scanning, OSV matching, direct versus transitive visibility, JSON output and a fix command, the summary in the repository description promises practical remediation guidance rather than a data dump.

The three selling points in the README's own table make the intent clearer. The first is the OWASP Lab Project status, described as peer-reviewed by the organisation behind the OWASP Top 10. The second is remediation first, with validated fix commands and parent-aware transitive guidance, explicitly not just CVE identifiers. The third is that it runs locally, so not your code and not your dependency tree leave your machine, and the page repeats that there is no account and no API key.

For a security tool, that local execution property is not a footnote. A dependency scanner normally wants to send a manifest somewhere to be analysed, and a tool that does not is a different category of thing, particularly for organisations whose source cannot go to a third party service.

## Scanning a lockfile rather than a manifest

The scan input is the lockfile, and that is the design choice that separates this from tools that parse a package.json.

A lockfile records the exact resolved version of every dependency in the tree, including transitive ones, so matching against it tells you what is actually installed rather than what a range would allow. The tool then matches those versions against OSV data, which is the open vulnerability database format, and the README describes this as OSV matching.

The second thing the tool does is separate direct from transitive findings. A vulnerability in a package you named in your manifest is your problem to fix directly, while one several levels down in the tree is usually fixed by bumping the direct parent. The README refers to parent-aware transitive guidance, which is the same idea expressed as remediation: the useful answer is which package to upgrade, not which identifier to look up.

That framing also explains the output. The usage section shows a basic scan, a verbose mode described as a full fix plan with dependency paths, and a fix option. So the tool has a path from detection to an action, and the verbose mode is where the dependency chain that produced a transitive finding becomes visible.

## The local advisory database and the better-sqlite3 caveat

Because the tool runs locally, it needs a local copy of the advisory information, and the README explains where that comes from.

CVE Lite CLI includes better-sqlite3, a native SQLite binding used for the local advisory database. During installation, npm may download a prebuilt binary or compile one from source, and the README warns that this can produce extra console output, clarifying that it is expected and that it is not CVE Lite CLI itself running an install script.

That warning is worth internalising before a team adopts the tool, because a native module compiling during install in a locked down build environment is a common source of friction, and the message that appears in the log looks alarming unless you know what it is.

The package metadata shows the rest of the dependency set, and it is short: better-sqlite3 for the database, fflate for compression, semver for version comparison, yaml for configuration, and yarn-lockfile for reading Yarn lockfiles. The semver and yaml entries are the ones that tell you what the tool actually does, since deciding whether a resolved version is affected by an advisory is a version range question, and lockfiles come in more than one format.

The binary is registered as cve-lite and points at ./dist/index.js, the package is ESM only with type set to module, and the engines field requires Node 20 or later.

## Getting it into the pipeline

The install is deliberately short. Globally:

```bash
npm install -g cve-lite-cli
cve-lite /path/to/project
```

Or for a one-off without installing anything:

```bash
npx cve-lite-cli /path/to/project
```

The usage section shows the same pattern with the flags that matter, where the basic scan is the default and the verbose mode gives the full fix plan with dependency paths:

```bash
cve-lite /path/to/project                   # basic scan
cve-lite /path/to/project --verbose         # full fix plan with dependency paths
```

There is a GitHub Action for the project and it is listed on the GitHub Marketplace, and the README points to a live workflow in the SolidJS repository as an example of it running in CI. It also records that the Government of British Columbia runs it as a required merge gate, that French government digital services use it, and that Valibot uses it.

The distinction between the two CI models is worth being deliberate about. As a required merge gate, the tool has to be fast, quiet on success and deterministic, because a developer waits on it. As an action that applies fixes, it needs a branch, because a machine rewriting a lockfile is a change that wants a diff and a review rather than a merge.

## The example fixtures as a specification

The examples directory is the most interesting part of the repository for anyone trying to understand what the tool does, and it is very large.

The names read like a catalogue of the cases that matter in dependency scanning. There are fixtures for direct and transitive findings, for a finding that is fixable and one that is not, for deep chains with and without a validated fix, for a dev-only finding, for a downgrade, for an exact pinned parent within range and an exact pinned intermediate, and for a case where the cooldown logic applies to a fresh fix. There are also real project fixtures, with directories for Astro, Cal.com, Gatsby, Cline, CopilotKit, Dyad, and Bun workspaces, plus a Bun project using a private registry.

That is a lot of scenarios, and the naming suggests the tool's behaviour is not a single algorithm. A finding that is only in a development dependency is different from one on a production path, an exact pin is different from a range that already contains the fix, and a downgrade is a different remediation from an upgrade. A tool that produced one undifferentiated list of identifiers would not need fixtures named this way.

The test infrastructure is correspondingly conventional: Jest with ts-jest, run through node with the experimental VM modules flag, a separate hygiene check script wired into both pretest and a lint target, and a script to build a fixture database for the tests.

## A release history that shows the tool correcting itself

The recent releases tell you what the project is actually spending its time on, and it is not feature work.

v1.37.0, dated 2026-09-23, is described as choosing where output files land, and stopping calling fixable findings unfixable. v1.38.0, dated 2026-10-04, is about override audits that admit what they could not check. v1.39.0, dated 2026-10-08, brings SPDX from the action and fixes two rules that were giving wrong advice.

Three releases in three weeks, and the subjects are all about correctness of the output and about being honest when the tool cannot verify something. That is a healthier sign than a sequence of new flags, because the value of a scanner is entirely in whether its findings and its advice are right.

The project also publishes an HTML report and a comparison document on its documentation site, along with a roadmap, and it is on the OpenSSF Best Practices programme with a passing badge.

One structural note for anyone building on it. The repository contains an action.yml, a .cve-lite/ directory that appears to hold configuration, a website/ directory, and a scripts/pr-scan-delta.mjs file that ships in the published package, which suggests the project supports comparing the scan result between a base and a change set, a common need in a pull request workflow.

## Where cve-lite-cli is the wrong tool

Three cases point elsewhere.

The first is a stack it does not cover. The tool is for JavaScript and TypeScript projects, with npm, pnpm, Yarn and Bun supported. A polyglot organisation with Python, Go, Java or Ruby services needs the equivalent tooling for each ecosystem, and the composition of those results is a separate piece of work that this tool does not do.

The second is a governance requirement for a full SBOM and a compliance record. The topic tags include cyclonedx and sbom-enabled, and the release notes mention SPDX output from the action, so there is SBOM related work in the project. But a local developer tool that prints fix commands is not the same artefact as a signed, versioned software bill of materials that a compliance auditor will accept, and treating the two as interchangeable is a mistake.

The third is a case where the local database is not the source of truth. The tool matches against a local advisory database populated from OSV data, and that is the point of the design, since nothing leaves the machine. The trade is that the findings are only as current as the local copy, and a team that wants a scanner to tell it what to do about a newly disclosed vulnerability needs to know how that database gets refreshed. The README does not document the refresh cycle in the section shown here, so that is a question to ask before making it a merge gate.

One last practical caution about the fix mode. A command that rewrites a dependency tree is a change to a lockfile, and the fixtures in the repository include cases named for downgrades and for pinned versions, which is a good sign that the tool is careful about that logic. It is still a change, and it belongs in a branch with a review.

## Conclusion

Adopt cve-lite-cli if you want a dependency vulnerability check that a developer can run without an account, that keeps your source and your dependency tree on your own machine, and that produces remediation steps rather than a list of identifiers. Do not adopt it as a replacement for a full software composition analysis platform, since it is a local CLI for JavaScript and TypeScript projects, and treat its findings as advisory for anything beyond your own dependencies. Verify three things first: which lockfile format your project uses, since the package managers supported are npm, pnpm, Yarn and Bun; whether the local advisory database is populated for the ecosystems you depend on, because the tool matches against OSV data and a missing local database means missing findings; and how the fix command behaves in CI, since a workflow that rewrites dependencies needs a branch and a review step rather than a merge gate. The licence is MIT, the last push was on 2026-10-20, and the newest release is v1.39.0 dated 2026-10-08.

## FAQ

### What is cve-lite-cli?

It is an OWASP Lab Project and a developer-friendly CLI that scans JavaScript and TypeScript projects for dependency vulnerabilities using local lockfiles and OSV data, with direct versus transitive visibility, a fix command and JSON output. Its emphasis is on remediation, printing what to run rather than only what is wrong.

### How do I install and run cve-lite-cli?

Run npm install -g cve-lite-cli and then cve-lite with a path to your project, or use npx cve-lite-cli with a path for a one-off. The package requires Node 20 or later and no account or API key is needed.

### Does cve-lite-cli send my code anywhere?

No. The README states that nothing leaves your machine, not your code and not your dependency tree, and the tool uses a local advisory database held in SQLite through the better-sqlite3 native binding. Note that npm may download a prebuilt binary or compile that binding during install, which produces extra console output that the README says is expected.

### Which package managers does cve-lite-cli support?

npm, pnpm, Yarn and Bun are listed as supported, and the dependency set includes yarn-lockfile and yaml for reading lockfiles and configuration. The manifest identifies the tool as a CLI for scanning JS/TS projects using local lockfiles and OSV.

### Can cve-lite-cli be used in CI?

Yes. There is a GitHub Action for the project listed on the GitHub Marketplace, and the README points to a live workflow in the SolidJS repository, notes that the Government of British Columbia runs it as a required merge gate, and mentions that French government digital services and Valibot use it.

## Sources

- [License: MIT](https://github.com/OWASP/cve-lite-cli/blob/main/LICENSE)
- [OWASP/cve-lite-cli on GitHub](https://github.com/OWASP/cve-lite-cli)
- [Project website](https://owasp.github.io/cve-lite-cli/)
- [README](https://github.com/OWASP/cve-lite-cli/blob/main/README.md)
- [Releases](https://github.com/OWASP/cve-lite-cli/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/owasp-cve-lite-cli
