cd /news/ai-tools/exorcist-a-ghost-hunter-for-your-pac… · home › topics › ai-tools › article
[ARTICLE · art-160102] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

Exorcist: a ghost hunter for your package.json

A developer built Exorcist, an open-source dependency health scanner for package.json that runs entirely in the browser and flags issues npm audit misses, including deprecated packages, functional duplicates, major-version lag, oversized bundles, copyleft licenses in permissive projects, and dependencies with no publish in two years. The tool uses Google's EmbeddingGemma 300M embedding model via Transformers.js on ONNX Runtime WebAssembly to detect functionally equivalent packages by cosine similarity above an 82% threshold, and rolls findings into a 0–100 health score. It is MIT licensed and available on GitHub.

by read5 min views1 publishedOct 29, 2026

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

Exorcist is a dependency health scanner for package.json — the checks

npm audit doesn't run. Drop in a file (or paste a GitHub repo URL) and it

finds the slow rot every Node project accumulates: deprecated packages,

functional duplicates nobody noticed they installed twice, packages a major

version or more behind, oversized bundles, copyleft licenses hiding in a

permissive project, and dependencies with no publish in two years. It rolls

everything into a single 0–100 health score and tells you what to do about

each finding.

For the theme — Ghost in the Machine — I leaned all the way in: a Victorian

broadside-poster UI, a blood-drip ceiling, flickering candles, a lantern that

follows your cursor, and a results screen presented as a morgue toe-tag.

Findings are "spirits" (Dead, Dormant, Cursed, Ancient, Bloated, Possessed,

and Resurrection for the alternatives it suggests). It's a bit much. That was

the point.

Live: https://exorcist-hf26-wk4.onrender.com

Click "Try a demo tome" on the landing page to scan a deliberately haunted

package.json — it has lodash+underscore duplicates, deprecated left-pad

and request, and a few other dependency sins, so you can see every check

fire without hunting down a real cursed project first.

No login, no setup, no data leaves your browser — see Privacy below.

Every Node.js project accumulates ghosts: deprecated packages nobody noticed, duplicates doing the same job, bloated bundles dragging down load times, licenses that conflict with yours, and ancient major versions three generations behind. These spirits hide in plain sight inside package.json, haunting your build long after anyone remembers inviting them in.

The invoicing-app fix is npm audit, which covers CVEs but not the slow rot — the functional duplicate you installed because you forgot you already had one, the 200kB library you pulled in for a function that ships with Node, the package whose last commit was in 2022. Exorcist catches those.

Fully local. Your package.json never leaves your machine. The ML model downloads once and runs in the browser tab via WebAssembly. No…

git clone https://github.com/ibrahim-iqbal/exorcist-hf26-wk4.git
cd exorcist-hf26-wk4
npm install
npm run dev

MIT licensed. Architecture and the full scan pipeline are written up in

docs/DESIGN.md

if you want the "how it actually works" version instead of the pitch.

The stack: React 19, TypeScript, Vite 8, Tailwind v4 for utility spots, and a

hand-built CSS theming layer (custom properties, no CSS-in-JS) for the poster

UI. Framer Motion and plain CSS keyframes handle the atmosphere — drips,

embers, the cursor-following lantern.

The scan runs entirely in the browser in seven stages:

Each stage reports progress so the UI can animate the summoning circle in

real time. If any stage fails (model can't load, registry unreachable), the

pipeline degrades gracefully — the checks that needed that data are skipped,

and the rest still run.

EmbeddingGemma 300M

— Google's open-weight embedding model from the Gemma family, running

entirely in-browser via Transformers.js

on ONNX Runtime WebAssembly. No API key, no inference server, no per-request

cost. It does two genuine jobs that keyword matching can't:

lodash and underscore share almost no words in their descriptions, but they're functionally the same thing. Exorcist embeds every package's npm description and flags pairs above an 82% cosine-similarity threshold.request is deprecated, it can surface axios or node-fetch based on what the package actually does. If the model can't load — offline, low memory, an older browser without

WebAssembly SIMD — the scan degrades gracefully. Those two checks get skipped

and the other five still run. No crash, no blank screen.

The rest of the pipeline (npm registry lookups, Bundlephobia bundle-size

checks, the scoring model) is plain TypeScript with no AI involved — the

model earns its place for the two checks that genuinely need semantic

understanding, not because "AI" sounded good on a feature list.

Because package.json is basically a map of your stack, your exposure, and

how far behind you are on patches — and I didn't want to ask anyone to upload

that to a server to find out if their dependencies were rotten.

An open-weight model running client-side means:

Open-weight models made this flow possible without those tradeoffs. That's

the whole pitch for "open innovation" here: the intelligence lives where the

data already is, instead of the data having to travel to where the

intelligence is.

The moment Exorcist stopped feeling like a side project and started feeling

like a real tool was the first time I ran it on one of my own production

package.json files — not the demo, not a test fixture, a project I

actually ship.

It found request. Deprecated since 2020. Still in my dependencies. I knew

request was deprecated — I'd read the notice years ago — but it was still

there, still being installed, still adding weight to every npm install,

because no scan I normally run flags "deprecated but functional." I'd walked

past that ghost every day without seeing it.

Then it found that lodash and underscore were both installed. Different

parts of the codebase pulled them in at different times. They do essentially

the same thing. Nobody noticed because the duplicate isn't visible in a

lockfile diff or a bundle report — you only see it if you compare what the

packages do, not what they're named. That's the check that needs

embeddings, and that's why I built it.

Exorcist is a tool for the kind of technical debt that hides in plain sight:

not security vulnerabilities or breaking changes, but the slow accumulation

of things that stopped being the right choice sometime between when you

installed them and now. The ghosts in your dependency tree aren't dramatic.

They're just quietly making everything a little heavier, a little slower, a

little harder to maintain — and nobody exorcises them because nobody looks.

Now something does.

render.yaml, building from source on every push. Built for Hacktoberfest 2026, Week 4: Ghost in the Machine.

── more in #ai-tools 4 stories · sorted by recency
── more on @exorcist 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/exorcist-a-ghost-hun…] indexed:0 read:5min 2026-10-29 · —