react-codeshift, the Package No One Wrote: Inside the Slopsquatting Pattern

Written by the Rafter Team

A package called react-codeshift quietly spread to 237 GitHub repositories earlier this year. Nobody wrote it. An LLM conflated two real npm packages — jscodeshift and react-codemod — and emitted react-codeshift in a single commit of 47 LLM-generated agent skills. The skills got forked, translated into Japanese, and propagated until security researcher Charlie Eriksen claimed the name preemptively, with no payload, just to keep an attacker from doing it first.
By the time Eriksen registered the name, AI agents executing the skills were pulling "a couple of daily downloads" from a package that did not exist when the LLM first hallucinated it.
The pattern has a name: slopsquatting. PSF's Seth Larson coined the term in 2024. Over the last twelve months it has crossed from research curiosity to in-the-wild risk — driven not by attacker innovation, but by the workflow shift inside coding agents.
If your team uses AI coding agents that run pip install, npm install, or equivalent inside tool-use loops, treat autonomous package installation as a privileged operation. The agent is functionally executing arbitrary third-party code as the developer. Sandbox the package manager, require human approval before new dependencies land in lockfiles, and pin dependency versions explicitly.
What slopsquatting is
Slopsquatting is what typosquatting becomes when the typo is generated by an LLM instead of a human.
The classic typosquatting pattern relies on a developer mistyping a package name and reaching a malicious package the attacker pre-registered on the assumption someone would slip up. It is a numbers game with low per-install yield, dependent on real human errors.
Slopsquatting is the same setup with a much higher yield. An LLM, asked to recommend a package for a task, hallucinates a name. The hallucinated name is plausible-sounding because it's drawn from the same statistical distribution as real package names — it conflates two existing packages, applies a common-suffix transform, or fills a niche that "obviously" should have a package and doesn't.
The developer, especially one curating LLM output rather than authoring it from scratch, runs the install. If an attacker has registered the hallucinated name first, the install runs the attacker's code.
The economics are inverted. Where typosquatting depends on a relatively small number of human errors per package, slopsquatting depends on the LLM consistently producing the same hallucinated name across many independent users. The same hallucination, repeated across many sessions, becomes a target.
What the research says
A USENIX 2025 study tested 16 models across 576,000 code samples. The hallucinated package names broke down into three categories:
- 38% conflations — names that mash two real packages together.
- 13% typo variants — names that drift one or two characters from a real package.
- 51% pure fabrications — names that don't match any real package by any reasonable metric.
Conflations are the most dangerous slice. They sound right. The pattern is "popular noun + popular suffix from an adjacent ecosystem," and they bypass the visual-inspection check because they look exactly like a package the developer would expect to exist.
The cross-ecosystem result is the other striking finding. Roughly 8.7% of Python-language hallucinations turned out to be valid JavaScript package names. That number rewards an attacker who registers a name in one ecosystem and waits for LLMs to recommend it in another. The slopsquatting attack surface is not constrained by language boundaries.
The huggingface-cli proof point
Researcher Bar Lanyado ran the experiment before slopsquatting had a name. He noticed models recommending huggingface-cli as the install command for the Hugging Face CLI tool. The actual install path is pip install -U "huggingface_hub[cli]" — the shorter name didn't exist as a package.
Lanyado registered huggingface-cli as a benign placeholder. In three months, the package collected over 30,000 authentic downloads. Alibaba's public repository README adopted the package name. None of those installs were attacker-driven; they were the result of the model consistently producing the hallucinated name and developers running the recommended command.
Imagine the same experiment with malicious code, and you have the worst-case shape of slopsquatting at scale.
The react-codeshift incident, in detail
react-codeshift is the cleanest in-the-wild example of slopsquatting reaching production-adjacent infrastructure.
The hallucination
The name was a conflation of two existing packages:
jscodeshift— Meta-maintained codemod runner, real, popular.react-codemod— React team-maintained codemod collection, real, popular.
The LLM produced react-codeshift as if it were a third member of the same family. The name is exactly the kind of plausibility a maintainer might miss on a quick read. It conjugates two well-known package names that share an ecosystem, share a use case, and share a vibe.
The propagation
The hallucinated name appeared in a single commit of 47 LLM-generated agent skills. Skill libraries are shared. Those skills got forked into 237 GitHub repositories. They were translated into Japanese, which forked them further. The chain of redistribution had no human author at any step deliberately introducing react-codeshift — every fork inherited it from the original LLM emission.
By the time security researcher Charlie Eriksen examined the package, AI agents were executing the skill instructions in tool-use loops and pulling daily downloads from a name that did not exist when the LLM first imagined it.
The save
Eriksen claimed react-codeshift on npm with a benign placeholder. No payload. The package became a documented IOC for the slopsquatting pattern rather than the entry point for a supply-chain compromise.
The next person to find a similarly propagated hallucinated name might not be a security researcher.
Why the curator workflow makes this worse
When a developer types pip install <package> themselves, there is a brief human moment where "wait, is that a typo?" can fire. The hallucinated name has to look right not only on the screen, but in the developer's mental model of what packages should exist. That is a real, if imperfect, defense.
When an autonomous agent emits the same instruction inside a tool-use loop, that moment evaporates. The developer is no longer the author of the package list. They are its curator. The path of least resistance, every time, is to let the install proceed.
The "vibe coding" workflow Socket's research team describes — developers acting as curators rather than authors — is exactly the configuration in which slopsquatting works at scale.
The curator workflow also creates compounding propagation. An agent skill that hallucinates a package is shared, forked, translated, and re-executed by other agents. Each re-execution is another download from the same hallucinated name. Each download reinforces the appearance of legitimacy. "This package has 200 weekly downloads from active GitHub repos" is a trust signal — except when the 200 downloads are from agents running a skill that hallucinated the name in the first place.
What to do
Treat autonomous package installation as a privileged operation
An agent that can run pip install or npm install in a tool-use loop is functionally executing arbitrary code as the developer. The mitigations are the same mitigations you'd apply to any privileged operation:
- Sandbox the agent's package manager. Run it in a container with no network access to anything other than your registry mirror.
- Run against a vetted registry mirror that maintains its own publisher allowlist. The mirror is the choke point.
- Require human approval before a new dependency lands in production lockfiles or manifests.
Verify the publisher, not just the name
The slopsquatting flag set is concrete and trainable as a check:
- Newly published packages (less than 90 days old).
- Packages with low or no download history.
- Packages whose names sit one or two Levenshtein steps from a popular dependency.
- Packages whose name is a conflation of two adjacent popular packages — the
react-codeshiftshape exactly.
A pip install or npm install that hits any of those conditions is worth a check at install time, not at audit time three weeks later.
Scan your full dependency tree on every push
A package introduced by an agent in a feature branch should be flagged the same way a hand-typed dependency would be — and it almost always isn't. Audit-mode dependency scans run on a cadence; agent installs run on a tool-use cadence. The diff that introduces a slopsquatted name is where you want the warning, not the audit run six weeks later.
Review your agent skill libraries
If your team is sharing or forking LLM-generated agent skills, audit them for package references the same way you'd audit a dependency manifest. A skill that hallucinated a package once will hallucinate it for everyone who forks it. The 47 skills in the react-codeshift incident were the propagation surface, not the package itself.
How Rafter helps
Rafter's Code Analysis Engine looks for known-vulnerable and known-suspicious dependency patterns on every push — including newly published packages, packages with low download history, and dependencies that drift from known-good names. The diff that introduces a slopsquatted dependency is exactly where the warning is most useful, before the next agent in the chain follows the lead and the package's "legitimacy" inflates from agent-driven downloads.
Rafter does not stop a hallucinated package from being recommended by your LLM. The model is upstream of any code scanner. What scanning shortens is the window between "an agent installed a hallucinated package in a feature branch" and "that hallucinated package is in your production lockfile."
Closing on the asymmetry
The supply chain has spent two decades hardening against typosquatters who rely on humans to mistype. The defenses are reasonable. Lockfiles, dependency review, and audit-mode scanning catch most of the typosquatting attack surface.
Slopsquatters do not need a human to mistype. They need an LLM to imagine a package that doesn't exist, and they need to register the name before the LLM imagines it for someone else. The asymmetry is in their favor on every axis: cheaper to find candidates, higher per-install yield, lower per-victim friction.
Every developer using an LLM to suggest dependencies is a free reconnaissance run. The defenses on the developer side are the same defenses, applied earlier in the install pipeline and aimed at a different threat model. The shift is treating "the LLM said to install it" as the same kind of input as "an untrusted user said to install it" — adversarial until verified.
Further reading
- Three Supply Chains, One Trust Relationship — the agent-runtime, marketplace, and registry as compounding trust relationships.
- PyTorch Lightning, Mini Shai-Hulud, and Malware That Signs Commits as Claude Code — what an attacker does when they target an AI-developer-tool dependency directly.
- Sandworm-mode: the npm worm that injected MCP servers — when the worm rewrites the assistant's config file rather than waiting for a hallucination.
Sources
- Aikido — Slopsquatting: AI Package Hallucination Attacks: https://www.aikido.dev/blog/slopsquatting-ai-package-hallucination-attacks
- Socket — How AI hallucinations are fueling a new class of supply chain attacks: https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks
- Snyk — Slopsquatting mitigation strategies: https://snyk.io/articles/slopsquatting-mitigation-strategies/
- Trend Micro — Slopsquatting: When AI Agents Hallucinate Malicious Packages: https://www.trendmicro.com/vinfo/us/security/news/cybercrime-and-digital-threats/slopsquatting-when-ai-agents-hallucinate-malicious-packages
- Wallet-stealer payloads in package ecosystems
- The trust-signal forgery economy
- A year of AI developer-tool supply-chain attacks