npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ghost-scan

v1.0.0

Published

Detect invisible Unicode payloads hiding in JS/TS projects

Readme

👻 ghost-scan

Detect invisible Unicode payloads hiding in your JavaScript/TypeScript projects.

Built by @JuanAtLarge after seeing this attack scale with AI-generated malicious npm packages.

The Attack

Malicious npm packages are hiding payloads in invisible Unicode characters — zero-width spaces, soft hyphens, BOM characters — that don't render in code editors or GitHub diffs. The payload gets decoded and passed to eval() at runtime. You never see it during review.

AI is now generating 100+ convincing fake packages per week. Manual review is useless against this.

What ghost-scan Does

  • Scans JS/TS files for invisible/zero-width Unicode characters
  • Flags files that combine invisible chars with eval(), new Function(), setTimeout(string), or child_process
  • Marks those as CRITICAL — invisible Unicode + eval is the attack signature
  • Works on your source code or full node_modules

Usage

No install needed:

npx ghost-scan

Or install globally:

npm install -g ghost-scan
ghost-scan

Options

# Scan current directory (skips node_modules by default)
npx ghost-scan

# Scan a specific path
npx ghost-scan ./src

# Include node_modules (slow but thorough)
npx ghost-scan . --node-modules

# Scan before installing a suspicious package
cd /tmp && mkdir test-pkg && cd test-pkg
npm pack <suspicious-package> && tar -xf *.tgz
npx ghost-scan ./package

Output

👻 ghost-scan — invisible Unicode payload detector
   by @JuanAtLarge | github.com/JuanAtLarge/ghost-scan

📂 Scanning: /your/project

🚨 CRITICAL node_modules/some-package/index.js
   Invisible chars found:
     • Zero-Width Space (U+200B) ×47
     • Soft Hyphen (U+00AD) ×12
   ⚡ Also contains: eval(), child_process
   → Invisible Unicode + eval pattern = likely malicious payload

🔍 1 file(s) flagged out of 1,847 scanned

🚨 CRITICAL findings detected. Do not run this code.

Exit Codes

| Code | Meaning | |------|---------| | 0 | Clean — no invisible Unicode found | | 1 | Warning — invisible Unicode found, no eval patterns | | 2 | Critical — invisible Unicode + eval/exec patterns found |

What It Detects

Invisible Unicode characters:

  • Zero-Width Space (U+200B)
  • Zero-Width Non-Joiner / Joiner (U+200C, U+200D)
  • Soft Hyphen (U+00AD)
  • BOM / Zero-Width No-Break Space (U+FEFF)
  • Deprecated Format Characters (U+206A-206F)
  • Invisible Math Operators (U+2061-2064)
  • Private Use Area characters

Dangerous execution patterns:

  • eval()
  • new Function()
  • setTimeout(string) / setInterval(string)
  • execSync() / child_process

Limitations

This catches the specific attack pattern described above. It won't catch every obfuscation technique. Defense in depth still applies — use a lockfile, audit your deps, don't install random packages.

License

MIT