@dis.dev/ghost-dep
v0.1.0
Published
A lightweight npm dependency guard that detects hallucinated, typosquatted, and suspicious package names before install.
Downloads
158
Maintainers
Readme
ghost-dep
A lightweight npm dependency guard that catches hallucinated, typosquatted, and suspicious package names before install — including ones buried several layers deep in your dependency tree, invisible to a tool that only checks package.json.
Zero runtime dependencies. Checks the live npm registry directly.
Why
AI coding assistants regularly suggest packages that don't exist. Attackers register those exact names and wait for someone to npm install them. That's slopsquatting.
Most detection tools only look at your declared dependencies. ghost-dep also walks the resolved dependency tree in package-lock.json, because hallucinated names increasingly show up as transitive dependencies — pulled in by a real package you trust, never listed in your package.json at all.
$ ghost-dep scan .
Scanned manifest: package.json
Summary: 0 flagged, 4 safe
Scanned lockfile: package-lock.json
- gpt-stream-utils-totally-fake-9182: hallucinated [express > body-parser > gpt-stream-utils-totally-fake-9182]
Summary: 1 flagged, 211 safeInstall
npm install -D ghost-depQuick start
# Check a single package name against the live registry
npx ghost-dep check openai-helper
# Scan a project's package.json AND package-lock.json (direct + transitive)
npx ghost-dep scan .
# Wrap an install command — blocks it if anything is flagged
npx ghost-dep install npm install lodash @types/node
# Check an install command without running it
npx ghost-dep check-command npm install lodash sketchy-pkgIf a flagged package is found, ghost-dep prints the reason and exits non-zero — so it fails CI and pre-commit hooks by default. This applies to lockfile-only findings too: a hallucinated package that's only visible three levels deep in package-lock.json still fails the scan, not just ones listed directly in package.json.
Risk levels
| Risk | Meaning |
|---|---|
| safe | Exists on npm, no suspicious signals |
| hallucinated | Does not exist on the npm registry |
| typosquatted | Exists, but is a near-match (edit distance ≤1-2) of a popular package name |
| suspicious | Exists, but matches an AI-hallucination naming pattern (e.g. openai-helper, gpt-plugin-utils) |
| invalid | Not a syntactically valid npm package name |
Typosquat checks skip scoped packages (@org/name) to avoid flagging legitimate first-party sub-packages like @eslint/eslintrc or @babel/core as typosquats of eslint or babel.
API
verifyPackageName(name)
import { verifyPackageName } from "ghost-dep";
const result = await verifyPackageName("openai-helper");
// {
// name: "openai-helper",
// valid: true,
// exists: false,
// risk: "hallucinated",
// reasons: ["Package name was not found on the npm registry."],
// didYouMean: null
// }scanPackageManifest(path)
Scans direct dependencies, devDependencies, peerDependencies, and optionalDependencies in package.json.
import { scanPackageManifest } from "ghost-dep";
const result = await scanPackageManifest("./package.json");scanPackageLockfile(path)
Walks the full resolved dependency graph in package-lock.json (supports lockfileVersion 1, 2, and 3), and reports the actual chain of packages that pulled each one in.
import { scanPackageLockfile } from "ghost-dep";
const result = await scanPackageLockfile("./package-lock.json");
// findings[].parentChain -> e.g. ["express", "body-parser", "some-hallucinated-pkg"]checkCommand(installCommand) / preInstallGuard(installCommand)
For wiring into agent harnesses, pre-commit hooks, or anywhere you want to intercept an install before it runs.
import { preInstallGuard } from "ghost-dep/agent";
// throws if any package in the command is flagged
await preInstallGuard("npm install openai-helper");import { checkCommand } from "ghost-dep/agent";
// returns findings without throwing
const findings = await checkCommand("npm install lodash sketchy-pkg");CLI
ghost-dep help
ghost-dep check <package-name>
ghost-dep scan [path]
ghost-dep install <npm install command>
ghost-dep check-command <install command>GitHub Action
- uses: ghost-dep/ghost-dep@v1
with:
path: .
fail-on-flagged: trueDevelopment
npm install
npm test # builds automatically first (pretest), then runs the full suiteThe test suite includes live checks against the real npm registry using real npm install-generated lockfiles (test/fixtures/real-express-tree, test/fixtures/real-react-tree) to catch heuristic false positives that mocked tests can't — this is how several false-positive bugs (proxy-addr, serve-static, @eslint/eslintrc) were actually found and fixed during development. Network access to registry.npmjs.org is required to run tests.
License
MIT
