Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More β†’
Socket
Sign inDemoInstall
Socket

knip

Package Overview
Dependencies
Maintainers
1
Versions
423
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

knip - npm Package Compare versions

Comparing version 0.13.0-members.1 to 0.13.0

dist/util/members.d.ts

3

dist/cli.js

@@ -9,3 +9,3 @@ #!/usr/bin/env node

import { measure } from './util/performance.js';
const { values: { help, dir, config: configFilePath, tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'include-entry-files': isIncludeEntryFiles = false, 'no-progress': noProgress = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', 'max-issues': maxIssues = '0', jsdoc: jsDoc = [], debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = parsedArgs;
const { values: { help, dir, config: configFilePath, tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'include-entry-files': isIncludeEntryFiles = false, 'no-progress': noProgress = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', 'max-issues': maxIssues = '0', debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = parsedArgs;
if (help) {

@@ -33,3 +33,2 @@ printHelp();

isShowProgress,
jsDoc,
debug: {

@@ -36,0 +35,0 @@ isEnabled: isDebug,

@@ -18,3 +18,2 @@ export const printHelp = () => {

--reporter-options Pass extra options to the reporter (as JSON string, see example)
--jsdoc Enable JSDoc parsing, with options: public
--debug Show debug output

@@ -30,3 +29,3 @@ --debug-level Set verbosity of debug output (default: 1, max: 2)

$ knip --dir packages/client --include files
$ knip -c ./knip.js --reporter compact --jsdoc public
$ knip -c ./knip.js --reporter compact
$ knip --ignore 'lib/**/*.ts' --ignore build

@@ -33,0 +32,0 @@ $ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'

@@ -12,3 +12,3 @@ import ts from 'typescript';

export const main = async (unresolvedConfiguration) => {
const { cwd, workingDir, configFilePath: configFilePathArg, tsConfigFilePath: tsConfigFilePathArg, include, exclude, ignore, gitignore, isIncludeEntryFiles, isDev, isShowProgress, jsDoc, debug, } = unresolvedConfiguration;
const { cwd, workingDir, configFilePath: configFilePathArg, tsConfigFilePath: tsConfigFilePathArg, include, exclude, ignore, gitignore, isIncludeEntryFiles, isDev, isShowProgress, debug, } = unresolvedConfiguration;
const updateMessage = getMessageUpdater(unresolvedConfiguration);

@@ -107,5 +107,2 @@ debugLogObject(debug, 1, 'Unresolved configuration', unresolvedConfiguration);

isShowProgress,
jsDocOptions: {
isReadPublicTag: jsDoc.includes('public'),
},
debug,

@@ -112,0 +109,0 @@ };

import path from 'node:path';
import { ts } from 'ts-morph';
import { partitionSourceFiles, _findDuplicateExportedNames, _hasReferencingDefaultImport, _findReferencingNamespaceNodes, _getExportedDeclarations, _findReferences, hasExternalReferences, hasInternalReferences, } from './util/project.js';
import { partitionSourceFiles, _findDuplicateExportedNames, _hasReferencingDefaultImport, _findReferencingNamespaceNodes, _getExportedDeclarations, _findReferences, hasExternalReferences, } from './util/project.js';
import { findUnusedClassMembers, findUnusedEnumMembers } from './util/members.js';
import { getType } from './util/type.js';

@@ -9,3 +10,3 @@ import { getDependencyAnalyzer } from './util/dependencies.js';

export async function findIssues(configuration) {
const { workingDir, report, jsDocOptions, debug } = configuration;
const { workingDir, report, debug } = configuration;
const { entryFiles, productionFiles, projectFiles, isIncludeEntryFiles } = configuration;

@@ -59,5 +60,5 @@ const { manifestPath } = configuration;

updateMessage('Connecting the dots...');
const isReportValues = report.exports || report.nsExports || report.classMembers;
const isReportTypes = report.types || report.nsTypes || report.enumMembers;
const isReportExports = report.exports || report.nsExports || report.classMembers;
if (report.dependencies || report.unlisted || report.duplicates || isReportExports || isReportTypes) {
if (report.dependencies || report.unlisted || report.duplicates || isReportValues || isReportTypes) {
usedProductionFiles.forEach(sourceFile => {

@@ -96,5 +97,5 @@ counters.processed++;

return;
if (!type && !isReportExports)
if (!type && !isReportValues)
return;
if (jsDocOptions.isReadPublicTag && ts.getJSDocPublicTag(declaration.compilerNode))
if (ts.getJSDocPublicTag(declaration.compilerNode))
return;

@@ -118,42 +119,24 @@ let identifier;

declaration.isKind(ts.SyntaxKind.InterfaceDeclaration)) {
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier);
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier);
}
else if (declaration.isKind(ts.SyntaxKind.EnumDeclaration)) {
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier);
const members = declaration.getMembers();
members.forEach(member => {
const refs = _findReferences(member);
if (hasExternalReferences(refs, filePath))
return;
if (hasInternalReferences(refs))
return;
addSymbolIssue('enumMembers', {
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier);
if (report.enumMembers)
findUnusedEnumMembers(declaration, filePath).forEach(member => addSymbolIssue('enumMembers', {
filePath,
symbol: member.getName(),
parentSymbol: identifier?.getText(),
});
});
}));
}
else if (declaration.isKind(ts.SyntaxKind.ClassDeclaration)) {
identifier = declaration.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier);
const members = declaration.getMembers();
members.forEach(member => {
const isPrivate = member.getCombinedModifierFlags() & ts.ModifierFlags.Private;
if (!isPrivate &&
(member.isKind(ts.SyntaxKind.PropertyDeclaration) || member.isKind(ts.SyntaxKind.MethodDeclaration))) {
const refs = _findReferences(member);
if (hasExternalReferences(refs, filePath))
return;
if (hasInternalReferences(refs))
return;
addSymbolIssue('classMembers', {
filePath,
symbol: member.getName(),
parentSymbol: identifier?.getText(),
});
}
});
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier);
if (report.classMembers)
findUnusedClassMembers(declaration, filePath).forEach(member => addSymbolIssue('classMembers', {
filePath,
symbol: member.getName(),
parentSymbol: identifier?.getText(),
}));
}
else if (declaration.isKind(ts.SyntaxKind.PropertyAccessExpression)) {
identifier = declaration.getLastChildByKindOrThrow(ts.SyntaxKind.Identifier);
identifier = declaration.getLastChildByKind(ts.SyntaxKind.Identifier);
}

@@ -160,0 +143,0 @@ else {

@@ -52,3 +52,2 @@ import { SourceFile } from 'ts-morph';

isShowProgress: boolean;
jsDoc: string[];
debug: {

@@ -74,5 +73,2 @@ isEnabled: boolean;

isShowProgress: boolean;
jsDocOptions: {
isReadPublicTag: boolean;
};
debug: {

@@ -79,0 +75,0 @@ isEnabled: boolean;

@@ -17,3 +17,2 @@ declare const _default: {

'reporter-options': string | undefined;
jsdoc: string[] | undefined;
debug: boolean | undefined;

@@ -20,0 +19,0 @@ 'debug-level': string | undefined;

@@ -18,3 +18,2 @@ import { parseArgs } from 'node:util';

'reporter-options': { type: 'string' },
jsdoc: { type: 'string', multiple: true },
debug: { type: 'boolean' },

@@ -21,0 +20,0 @@ 'debug-level': { type: 'string' },

{
"name": "knip",
"version": "0.13.0-members.1",
"version": "0.13.0",
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",

@@ -28,3 +28,3 @@ "keywords": [

"scripts": {
"knip": "node ./dist/cli.js --jsdoc public",
"knip": "node ./dist/cli.js",
"test": "globstar -- node --loader tsx --test \"test/*.spec.ts\"",

@@ -34,2 +34,3 @@ "watch": "tsc --watch",

"prepublishOnly": "npm test && npm run build && npm run knip",
"format": "remark README.md -o",
"release": "release-it"

@@ -60,2 +61,4 @@ },

"release-it": "15.5.0",
"remark-cli": "11.0.0",
"remark-preset-webpro": "0.0.1",
"tsx": "3.11.0",

@@ -70,2 +73,7 @@ "type-fest": "3.1.0",

},
"remarkConfig": {
"plugins": [
"preset-webpro"
]
},
"engines": {

@@ -72,0 +80,0 @@ "node": ">=16.17.0 <17 || >=18.6.0"

@@ -20,8 +20,7 @@ # βœ‚οΈ Knip

- [x] Finds **unused files, dependencies and exports**.
- [x] Finds dependencies not listed in `package.json`.
- [x] Verifies that exported symbols are actually used in other files, even when part of an imported namespace.
- [x] Supports JavaScript inside TypeScript projects (`"allowJs": true`).
- [x] Finds duplicate exports of the same symbol.
- [x] Supports JavaScript ES Module-based projects without a `tsconfig.json`.
- [x] Features multiple [reporters][1] and supports [custom reporters][2].
- [x] Finds used dependencies not listed in `package.json`.
- [x] Finds duplicate exports.
- [x] Supports JavaScript (without `tsconfig.json`, or TypeScript `allowJs: true`).
- [x] Features multiple [reporters][1] and supports [custom reporters][2] (think JSON and `CODEOWNERS`)
- [x] Run Knip as part of your CI environment to detect issues and prevent regressions.

@@ -36,2 +35,18 @@ Knip really shines in larger projects. A little bit of configuration will pay off, I promise. A comparison with similar

## Roadmap
Please report any false positives by [opening an issue in this repo][6]. Bonus points for adding a public repository or
opening a pull request with a directory and example files in `test/fixtures`. Correctness and bug fixes have priority
over new features:
### Upcoming Features
- [ ] Find unused members of classes and enums (#11 and #20).
- [ ] Custom dependency resolvers: find dependencies used in npm scripts.
- [ ] Custom dependency resolvers: find unused and unlisted plugins for Webpack, ESLint & Babel, etc. (#7)
- [ ] Smart default configurations and more fine-grained configuration options.
- [ ] Full support for monorepos (partial [monorepos support][7] with `--dir` exists).
- [ ] Fix issues: remove `export` keyword, uninstall unused dependencies, delete files (like `--fix` of ESLint).
- [ ] Add more reporters and report customization options (#3).
## Installation

@@ -41,3 +56,3 @@

Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.3. Knip is _cutting edge!_
Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.6. Knip is _cutting edge!_

@@ -73,3 +88,3 @@ ## Usage

![How it works][6]
![How it works][8]

@@ -85,5 +100,5 @@ ## Options

--dir Working directory (default: current working directory)
--include Report only listed issue type(s) (see below)
--exclude Exclude issue type(s) from report (see below)
--ignore Ignore files matching this glob pattern (can be set multiple times)
--include Report only listed issue type(s), can be repeated
--exclude Exclude issue type(s) from report, can be repeated
--ignore Ignore files matching this glob pattern, can be repeated
--no-gitignore Don't use .gitignore

@@ -96,3 +111,2 @@ --dev Include `devDependencies` in report(s)

--reporter-options Pass extra options to the reporter (as JSON string, see example)
--jsdoc Enable JSDoc parsing, with options: public
--debug Show debug output

@@ -102,3 +116,3 @@ --debug-level Set verbosity of debug output (default: 1, max: 2)

Issue types: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates
Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates

@@ -109,3 +123,3 @@ Examples:

$ knip --dir packages/client --include files
$ knip -c ./knip.js --reporter compact --jsdoc public
$ knip -c ./knip.js --reporter compact
$ knip --ignore 'lib/**/*.ts' --ignore build

@@ -116,10 +130,2 @@ $ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'

## Performance
πŸš€ Knip is considerably faster when only the `files` and/or `duplicates` types are included. Finding unused exports
requires deeper analysis (`exports`, `nsExports`, `types`, `nsTypes`). The following example commands do the same:
knip --include files --include duplicates
knip --include files,duplicates
## Reading the report

@@ -131,10 +137,17 @@

- `files` - Unused files: did not find references to this file
- `dependencies` - Unused dependencies: did not find references to this dependency
- `unlisted` - Unlisted dependencies: imported dependencies, but not listed in package.json (1)
- `exports` - Unused exports: did not find references to this exported variable
- `nsExports` - Unused exports in namespaces: did not find direct references to this exported variable (2)
- `types` - Unused types: did not find references to this exported type
- `nsTypes` - Unused types in namespaces: did not find direct references to this exported variable (2)
- `duplicates` - Duplicate exports: the same thing is exported more than once with different names from the same file
- Dependencies (`package.json`)
- `dependencies` - Unused dependencies: did not find references to this dependency
- `unlisted` - Unlisted dependencies: used dependencies, but not listed in package.json (1)
- Values (JavaScript)
- `exports` - Unused exports: did not find references to this exported variable
- `nsExports` - Unused exports in namespaces: did not find direct references to this exported variable (2)
- `classMembers` - Unused class members: did not find references to this member of the exported class
- Types (TypeSscript)
- `types` - Unused types: did not find references to this exported type
- `nsTypes` - Unused types in namespaces: did not find direct references to this exported variable (2)
- `enumMembers` - Unused enum members: did not find references to this member of the exported enum
- `duplicates` - Duplicate exports: the same thing is exported more than once
Notes:
1. This includes dependencies that could not be resolved. For instance, what does `unresolved/dir/module` mean?

@@ -160,10 +173,47 @@ - To target something in the (missing) `node_modules/unresolved` package?

file. If this is not the case, it can be removed.
- Duplicate exports can be removed to export only once, make sure to import that everywhere.
πŸ” Repeat the process to reveal new unused files and exports. Sometimes it's so liberating to remove things!
## Production versus non-production code
## Performance
πŸš€ Knip finds issues of type `files`, `dependencies`, `unlisted` and `duplicates` very fast. Finding unused exports
requires deeper analysis (`exports`, `nsExports`, `classMembers`, `types`, `nsTypes`, `enumMembers`).
Use `--include` to report only specific issue types (the following example commands do the same):
knip --include files --include dependencies
knip --include files,dependencies
Use `--exclude` to ignore reports you're not interested in:
knip --include files --exclude classMembers,enumMembers
Use `--performance` to see where most of the time is spent.
## Configuration
### Libraries versus Applications
Libraries and applications are identical when it comes to files and dependencies: whatever is unused should be removed.
Yet libraries usually have exports meant to be used by other libraries or applications. Such public variables and types
in libraries can be marked with the JSDoc `@public` tag:
```js
/**
* Merge two objects.
*
* @public
*/
export const merge = function () {};
```
Knip does not report public exports and types as unused.
### Production versus non-production code
Feels like you're getting too many false positives? Let's talk about `entryFiles` and `projectFiles`.
### Production code
#### Production code

@@ -180,3 +230,3 @@ The default configuration for Knip is very strict and targets production code. Non-production files such as tests should

### Non-production code
#### Non-production code

@@ -260,5 +310,4 @@ Non-production code includes files such as unit tests, end-to-end tests, tooling, scripts, Storybook stories, etc. Think

A good example of a large project setup is a monorepo. Let's take an example (Nx) project configuration using Next.js,
Jest and Storybook, which has multiple apps and libs. They are not published separately and don't have their own
`package.json`.
Let's take another example Nx project configuration using Next.js, Jest and Storybook, which has multiple apps and libs.
They are not published separately and don't have their own `package.json`.

@@ -294,6 +343,6 @@ This configuration file can also be a JavaScript file, which allows to add logic and/or comments (e.g. `knip.js`):

- [`json`](#json)
- [`symbol`](#symbol-default) (default)
- [`compact`](#compact)
- [`codeowners`](#code-owners)
- [`json`][9]
- [`symbol`][10] (default)
- [`compact`][11]
- [`codeowners`][12]

@@ -353,34 +402,27 @@ ### Custom Reporters

The keys match the [known issue types](#reading-the-report).
The keys match the [known issue types][13].
#### Usage Ideas
Use tools like [miller](https://github.com/johnkerl/miller) or [jtbl](https://github.com/kellyjonbrazil/jtbl) to consume
the JSON and render a table in the terminal.
Use tools like [miller][14] or [jtbl][15] to consume the JSON and render a table in the terminal.
##### Table
```
$ npx knip --reporter json | mlr --ijson --opprint --no-auto-flatten cat
file owners files unlisted exports types duplicates
src/Registration.tsx @org/owner true react lowercaseFirstLetter, RegistrationBox RegistrationServices, RegistrationAction Registration, default
src/ProductsList.tsx @org/team false - - ProductDetail -
```
$ npx knip --reporter json | mlr --ijson --opprint --no-auto-flatten cat
file owners files unlisted exports types duplicates
src/Registration.tsx @org/owner true react lowercaseFirstLetter, RegistrationBox RegistrationServices, RegistrationAction Registration, default
src/ProductsList.tsx @org/team false - - ProductDetail -
##### Markdown Table
```
$ npx knip --reporter json | mlr --ijson --omd --no-auto-flatten cat
| file | owners | files | duplicates |
| --- | --- | --- | --- |
| src/Registration.tsx | @org/owner | true | Registration, default |
| src/ProductsList.tsx | @org/team | false | |
```
$ npx knip --reporter json | mlr --ijson --omd --no-auto-flatten cat
| file | owners | files | duplicates |
| --- | --- | --- | --- |
| src/Registration.tsx | @org/owner | true | Registration, default |
| src/ProductsList.tsx | @org/team | false | |
Include specific issue types and/or replace the `cat` command with `put` for clean output:
```
npx knip --include files,duplicates --reporter json | mlr --ijson --opprint --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'
npx knip --reporter json | mlr --ijson --omd --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'
```
npx knip --include files,duplicates --reporter json | mlr --ijson --opprint --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'
npx knip --reporter json | mlr --ijson --omd --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'

@@ -482,16 +524,18 @@ ### More Output Examples

| Feature | **knip** | [depcheck][7] | [unimported][8] | [ts-unused-exports][9] | [ts-prune][10] | [find-unused-exports][11] |
| --------------------------------- | :------: | :-----------: | :-------------: | :--------------------: | :------------: | :-----------------------: |
| Unused files | βœ… | - | βœ… | - | - | - |
| Unused dependencies | βœ… | βœ… | βœ… | - | - | - |
| Unlisted dependencies | βœ… | βœ… | βœ… | - | - | - |
| [Custom dependency resolvers][12] | ❌ | βœ… | ❌ | - | - | - |
| Unused exports | βœ… | - | - | βœ… | βœ… | βœ… |
| Duplicate exports | βœ… | - | - | ❌ | ❌ | ❌ |
| Search namespaces | βœ… | - | - | βœ… | ❌ | ❌ |
| Custom reporters | βœ… | - | - | - | - | - |
| Pure JavaScript/ESM | βœ… | βœ… | βœ… | - | - | βœ… |
| Configure entry files | βœ… | ❌ | βœ… | ❌ | ❌ | ❌ |
| [Support monorepos][13] | 🟠 | - | - | - | - | - |
| ESLint plugin available | - | - | - | βœ… | - | - |
| Feature | **knip** | [depcheck][16] | [unimported][17] | [ts-unused-exports][18] | [ts-prune][19] | [find-unused-exports][20] |
| :-------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: | :-----------------------: |
| Unused files | βœ… | - | βœ… | - | - | - |
| Unused dependencies | βœ… | βœ… | βœ… | - | - | - |
| Unlisted dependencies | βœ… | βœ… | βœ… | - | - | - |
| [CustomΒ dependencyΒ resolvers][21] | ❌ | βœ… | ❌ | - | - | - |
| Unused exports | βœ… | - | - | βœ… | βœ… | βœ… |
| UnusedΒ classΒ members | βœ… | - | - | - | - | - |
| UnusedΒ enumΒ members | βœ… | - | - | - | - | - |
| Duplicate exports | βœ… | - | - | ❌ | ❌ | ❌ |
| Search namespaces | βœ… | - | - | βœ… | ❌ | ❌ |
| Custom reporters | βœ… | - | - | - | - | - |
| JavaScript support | βœ… | βœ… | βœ… | - | - | βœ… |
| Configure entry files | βœ… | ❌ | βœ… | ❌ | ❌ | ❌ |
| [Support monorepos][22] | 🟠 | - | - | - | - | - |
| ESLint plugin available | - | - | - | βœ… | - | - |

@@ -507,7 +551,8 @@ βœ… = Supported, ❌ = Not supported, - = Out of scope

Using a string like `"plugin:cypress/recommended"` in the `extends` property of a `.eslintrc.json` in a package
directory of a monorepo is nice for DX. But Knip will need some help to find it and to understand this _resolves to_ the
`eslint-plugin-cypress` _dependency_. Or see it is not listed in `package.json`. Or that the dependency is still listed,
directory of a monorepo is nice for DX. But Knip will need some help to find it and to understand this resolves to the
`eslint-plugin-cypress` dependency. Or see it is not listed in `package.json`. Or that the dependency is still listed,
but no longer in use. Many popular projects reference plugins in similar ways, such as Babel, Webpack and Storybook.
Big compliments to [depcheck][15] which already does this! They call this "specials". [Knip has this ambition][16], too.
Big compliments to [depcheck][23] which already does this! They call this "specials". This is on [Knip's roadmap][24],
as well, with the additional ambition to also find used dependencies that are not listed in `package.json`.

@@ -534,12 +579,20 @@ unimported is strict in this regard and works based on production files and `dependencies`, so does not have custom

[5]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
[6]: ./assets/how-it-works.drawio.svg
[7]: https://github.com/depcheck/depcheck
[8]: https://github.com/smeijer/unimported
[9]: https://github.com/pzavolinsky/ts-unused-exports
[10]: https://github.com/nadeesha/ts-prune
[11]: https://github.com/jaydenseric/find-unused-exports
[12]: #custom-dependency-resolvers
[13]: #monorepos-1
[14]: #monorepos
[15]: https://github.com/depcheck/depcheck#special
[16]: https://github.com/webpro/knip/issues/7
[6]: https://github.com/webpro/knip/issues
[7]: #monorepos
[8]: ./assets/how-it-works.drawio.svg
[9]: #json
[10]: #symbol-default
[11]: #compact
[12]: #code-owners
[13]: #reading-the-report
[14]: https://github.com/johnkerl/miller
[15]: https://github.com/kellyjonbrazil/jtbl
[16]: https://github.com/depcheck/depcheck
[17]: https://github.com/smeijer/unimported
[18]: https://github.com/pzavolinsky/ts-unused-exports
[19]: https://github.com/nadeesha/ts-prune
[20]: https://github.com/jaydenseric/find-unused-exports
[21]: #custom-dependency-resolvers
[22]: #monorepos-1
[23]: https://github.com/depcheck/depcheck#special
[24]: #roadmap
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚑️ by Socket Inc