DEV Community

Alan
Alan

Posted on

I Published an npm Package. Someone Used the Same Name 8 Days Later.

Eight days after I published my first npm package, I found a GitHub repo with the exact same name. Different author, different language, different country. Same name, same domain (AI agent identity), even some of the same crypto primitives.

The package has about 4k lines of TypeScript, four workspace packages, 365 tests. Not a weekend project. So finding a repo called the same thing, first commit dated eight days after my npm publish, with a version tag of "v6.0" on that first commit... that was a weird morning.

npm timestamps don't lie

First thing I did was check what I actually had on my side.

$ npm view my-package time
{
  '0.0.1': '2026-03-01T...',
  '0.2.0': '2026-03-05T...',
  '0.2.5': '2026-03-05T...',
  '0.2.8': '2026-03-08T...'
}
Enter fullscreen mode Exit fullscreen mode

npm publish timestamps are immutable. Git commits can be rebased and rewritten. npm timestamps can't.

Their first commit: March 9. My 0.0.1: March 1. That settled the priority question. But I did a lot of other stuff anyway, because panic is a hell of a motivator.

So how do naming collisions actually work?

Here's the thing I didn't fully appreciate before this happened: npm, PyPI, and crates.io are completely independent namespaces. Owning my-package on npm gives you zero claim to my-package on PyPI. There's no cross-registry reservation system. There's no trademark-like protection unless you actually have a trademark.

The other project was in Python. They couldn't use my npm name because I already had it. So they published on PyPI and built a website instead.

Totally legal. Feels weird, but totally legal.

The 45-minute panic

Here's what I did in the first hour after finding the repo:

Checked PyPI. My name wasn't taken. Registered it immediately with a placeholder package.

$ pip install twine build
# created a minimal pyproject.toml with just the name and version
$ python -m build && twine upload dist/*
Enter fullscreen mode Exit fullscreen mode

PyPI's registration process is straightforward but I'd never done it before. Spent 15 minutes figuring out that you need a pyproject.toml now, not a setup.py. The Python packaging ecosystem changes its mind about this every two years.

Checked crates.io. Also not taken. Registered four variations.

$ cargo init my-package --lib
$ cargo publish --allow-dirty
Enter fullscreen mode Exit fullscreen mode

crates.io requires a valid Cargo.toml with a license field and a non-empty src/lib.rs. My placeholder packages have exactly one line of Rust:

// placeholder - real implementation coming
Enter fullscreen mode Exit fullscreen mode

Is this a good use of package registries? Probably not. But the alternative was watching someone else grab them.

Checked the GitHub username. Taken, but by an inactive account with zero repos. Nothing I can do about that.

Total time: about 45 minutes. Could have been 10 if I'd done this before the first npm publish.

What tipped me off

I wasn't actively searching for copycats. I was checking if anyone had used a similar name before I registered on more platforms. Standard due diligence, a week late.

The repo had 32 commits in 3 days. All by one person. The first commit was tagged "v6.0", which is a bold move for a repo that didn't exist the day before. Most of the code looked AI-generated (one commit had a co-author tag from an AI assistant). There was a Discord bot, a Supabase backend, some Solana stubs that didn't compile.

I don't want to get into whether this counts as "copying." The name is unusual enough that it's not a coincidence. But the implementation was completely different, and open source doesn't have naming courts.

What bothered me more than the copying was realizing how exposed I'd been. Eight days with an npm package and zero presence anywhere else. If they'd moved faster, they could have grabbed the PyPI name first.

What I'd actually recommend

If you're publishing an open source package with a distinctive name, do this stuff on day one. Not day eight.

Before your first npm publish:

Check these registries even if you have no plans to publish there:

  • PyPI (pip install your name, see if it 404s)
  • crates.io (search, or cargo search your-name)
  • The GitHub username
  • The .com / .dev / .ai domains

In your package.json:

{
  "homepage": "https://github.com/your-org/your-package",
  "repository": {
    "type": "git",
    "url": "https://github.com/your-org/your-package"
  }
}
Enter fullscreen mode Exit fullscreen mode

Sounds obvious but I didn't have the homepage field until after the incident. Google uses it when indexing npm packages.

In your README, near the top:

Something like "Originally published March 2026 on npm" with a link. Not aggressive, just a timestamp that lives in your repo.

Register placeholder packages on at least PyPI and crates.io. A minimal package with just a name and description takes 5 minutes per registry. The cost is near zero. The alternative is doing it in a panic at 11pm on a weekday.

The version tag thing still bugs me

Their repo's first commit was tagged v6.0. Not v0.1.0, not v1.0.0. Version 6.

I can think of two reasons to do this. One is that they had five previous major versions in a private repo and decided to open-source at v6. The other is that they wanted the project to look mature.

The repo had zero stars, zero forks, zero issues, one contributor. I'll let you decide which explanation is more likely.

npm doesn't care, and that's fine

I reached out to npm support just to understand the policy. There isn't one for cross-platform naming conflicts. npm's stance is basically: you own the name on npm, that's it. What happens on PyPI or GitHub is outside their scope.

Which is the right answer, honestly. A centralized cross-platform naming authority would be a nightmare. Imagine disputing a crate name because you own the npm package. The governance complexity alone would be unworkable.

The tradeoff is that defensive registration falls on you. Nobody else is going to protect your name across registries.

Eight days is a long time

That's the actual takeaway for me. I built the thing, tested extensively, published to npm, and then just... didn't think about other registries. For eight days. In a space where someone can scaffold an entire project with AI assistance in a weekend.

If you're publishing something with a name you care about, spend the extra 30 minutes on day one. It's boring, it feels premature, and it will save you a very unpleasant surprise.

My package registrations now look like this:

npm:       ✅ (day 1)
PyPI:      ✅ (day 9, should have been day 1)
crates.io: ✅ (day 9)
GitHub org: ✅ (day 1)
Enter fullscreen mode Exit fullscreen mode

Four out of four. Would have been a lot less stressful if I'd done them all on the same day.

Top comments (0)