# Retire.js: scanning JavaScript libraries that never appear in a package manifest

> Retire.js finds JavaScript libraries with known vulnerabilities, including the ones copied into source control without a manifest, and can emit a CycloneDX SBOM. The CLI is the part worth adopting; the browser extensions are convenience layers.

**RetireJS/retire.js** — scanner detecting the use of JavaScript libraries with known vulnerabilities. Can also generate an SBOM of the libraries it finds.

- Repository: https://github.com/RetireJS/retire.js
- Website: https://retirejs.github.io/retire.js/
- Stars: 4,181 · Forks: 442
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/retirejs-retire-js

## The dependency that never shows up in npm ls

Package managers only audit what they installed. A large class of JavaScript in production arrived another way: a minified jQuery copied into a static folder, a bundled plugin dropped into source control, a library pulled from a CDN and pinned by a version string nobody revisits. Nothing in package.json mentions it, so npm audit has nothing to say about it. Retire.js exists for exactly that gap. The README frames the problem with the OWASP Top 10 entry added in 2013, "Using Components with Known Vulnerabilities", and states the tool was created to identify library versions with known vulnerabilities, "especially those that are not in package manifests, but simply downloaded and put in source control". The audience follows from that: web application developers, penetration testers working through Burp or OWASP ZAP, and anyone who has to answer the question of which third-party JavaScript a site actually serves.

## How the scanner decides a file is a vulnerable library

Retire.js works by fingerprinting, not by reading a lockfile. It walks the files it is pointed at, matches their contents against a repository of known library signatures, and resolves each match to a version. Vulnerability data lives in the repository's repository/ directory, which the README describes as the vulnerability repo whose maintenance donations are intended to fund. That separation matters operationally: the scanner is only as current as the signature set it carries, and the signature set is a separate artifact from the code. Anything the fingerprinting cannot recognise is invisible. A library that has been renamed, heavily rewritten, or wrapped in a custom bundle may not match a signature, and the tool will report nothing rather than guess. The same mechanism is what makes it work on files with no manifest at all, which is the whole point.

## Installing the Retire.js command line scanner and running it once

The README gives the install as a global npm package, run from the source folder of the application you want to scan. Node and npm need to be present first; the README links to the npm installation instructions for that step.

```bash
$ npm install -g retire
$ retire
```

The bare retire invocation scans the current directory and reports any libraries it recognises together with the vulnerabilities attached to those versions. By default the process exits with code 13 when it finds vulnerabilities, which the README notes can be overridden with --exitwith 0. That default is deliberate and it is the first thing to check before putting the command in a pipeline, because a non-zero exit from a scanner is indistinguishable from a broken build unless you decide which one you want.

SBOM generation uses the same command with an output format flag:

```bash
$ retire --outputformat cyclonedx
```

The README states that cyclonedx produces CycloneDX 1.4 XML. For JSON, and for newer spec versions, the flags are cyclonedxJSON for 1.4, cyclonedxJSON1_6 and cyclonedxJSON1_7. The cyclonedxJSON1_6_VEX and cyclonedxJSON1_7_VEX variants additionally include a vulnerabilities section, which is what you want if the consumer of the SBOM needs the findings rather than just the component list.

## CycloneDX output: pick the variant before you pick the pipeline

The naming of the output formats is the part most likely to cause a bad afternoon. Four JSON variants and one XML default exist, and the README does not describe a compatibility matrix between them. What it does say is precise: cyclonedx is XML at spec 1.4, cyclonedxJSON is JSON at 1.4, cyclonedxJSON1_6 and cyclonedxJSON1_7 are the newer JSON specs, and only the two _VEX variants carry a vulnerabilities section. If your SBOM consumer expects JSON and you pass --outputformat cyclonedx, you get XML and the ingest step fails. If you need vulnerability data in the document and you pass cyclonedxJSON1_7, the README indicates you get components without the vulnerabilities section. Decide which of these five strings your toolchain accepts before the command goes into CI.

## Where Retire.js is the wrong instrument

Retire.js is a fingerprinting scanner, and that defines its blind spots. It cannot tell you about a vulnerability in code you wrote, only in libraries it recognises. It cannot resolve a transitive dependency tree, because it does not build one. The README does not document rollback, suppression semantics beyond the existence of an example.retireignore.json file at the top level of the repository, or how a finding is tied to a specific patch version. A team that already has a complete and trustworthy manifest for every dependency gains comparatively little here, because their package manager's audit path already covers declared packages. The case where Retire.js pays for itself is the opposite one: a directory tree of served JavaScript with no reliable inventory. Note also that the README marks the Firefox extension as deprecated and asks for a maintainer, and the Chrome extension is explicitly "Not officially available in the Chrome web store", so browser-based use is the weaker half of the project.

## Retire.js against a package manager audit, and against a headless site scanner

The nearest alternative in most workflows is npm audit, and the difference is one of input. npm audit reads the resolved dependency graph from a lockfile and queries an advisory database keyed to package names and versions. Retire.js reads file contents and matches fingerprints. Run npm audit on a project whose vulnerable jQuery was downloaded into public/js and it reports nothing, because that file was never a dependency. Run Retire.js on the same project and it can flag the file. The reverse also holds: for a transitive dependency buried four levels deep in node_modules, the lockfile-based tool has the graph and Retire.js has to recognise the file on disk. They answer different questions, and the README's own framing of the problem makes clear which one Retire.js was built for. A second alternative within the same project family is the retire-site-scanner, a separate repository the README lists as the headless way to scan a live web site, as opposed to loading the Chrome or Firefox extension and browsing. If your goal is to check what a deployed site actually serves rather than what is in a source folder, that is the variant to look at.

## Maintenance, licensing and what an upgrade actually costs

The repository is not archived and its last push was on 2026-09-21, two days before this writing, with releases 5.5.0, 5.6.0 and 5.7.0 all dated 2026-08-22, 2026-08-21 and 2026-08-22 respectively. That is a fast release cadence in a short window, which is consistent with a project that keeps its vulnerability repository current, but it also means the CLI can change between minor versions. The licence is Apache-2.0, which permits commercial and closed-source use and requires that you preserve the licence and notice files; the repository carries LICENSE.md and NOTICE.md at the top level for that purpose. This is not legal advice, and the NOTICE.md file is the document to read if you redistribute the tool. The real upgrade cost is not the npm package, it is the signature set: a scanner pinned to an old version reports an old world, so the version you install is the version of the vulnerability data you get.

## Conclusion

Adopt Retire.js if your application ships JavaScript that was downloaded rather than declared in a manifest, or if you need a CycloneDX SBOM from a directory tree. Do not adopt it as a replacement for dependency auditing of declared npm packages, and do not rely on the Firefox extension, which the README marks as deprecated. Before wiring it into a build, verify two things yourself: what exit code your pipeline expects against the default of 13, and which of the cyclonedxJSON1_6 or cyclonedxJSON1_7 variants your SBOM consumer accepts, since the plain cyclonedx output is XML only.

## FAQ

### What is Retire.js used for?

It scans a web or Node application for JavaScript libraries with known vulnerabilities, including libraries that were downloaded and committed to source control rather than declared in a package manifest. It can also generate a CycloneDX SBOM of the libraries it finds.

### Is the Retire.js extension available in Chrome?

The README states the Chrome extension is not officially available in the Chrome web store. The extension source is in the chrome directory of the repository, and the README also lists a Burp extension and an OWASP ZAP add-on as supported integration paths.

### How do I install Retire.js?

The README gives a global npm install, then running the command from the source folder of the application you want to scan. Node and npm have to be installed first, and the README links to the npm installation instructions for that.

### How do I use Retire.js in Burp?

Retire.js is available as a Burp plugin adapted by h3xstream, linked from the README as burp-retire-js. Separately, the OWASP ZAP team supports a Retire.js add-on available through the ZAP Marketplace and included by default in ZAP weekly releases.

### Is Retire.js an alternative to npm audit?

They take different inputs. npm audit works from the resolved dependency graph in a lockfile, while Retire.js fingerprints file contents, which is how it catches libraries that were downloaded into source control and never became dependencies. The README frames that gap as the reason the tool exists.

## Sources

- [License: Apache-2.0](https://github.com/RetireJS/retire.js/blob/master/LICENSE)
- [Project website](https://retirejs.github.io/retire.js/)
- [README](https://github.com/RetireJS/retire.js/blob/master/README.md)
- [Releases](https://github.com/RetireJS/retire.js/releases)
- [RetireJS/retire.js on GitHub](https://github.com/RetireJS/retire.js)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/retirejs-retire-js
