Safeguard
Open Source

core-js on npm: Security Review and Safe Usage

A security and sustainability review of core-js on npm: the postinstall history, the maintainer funding crisis, and how to keep this near-universal dependency safe.

Aisha Rahman
Security Analyst
6 min read

The biggest security consideration for core-js on npm is not a specific CVE but sustainability risk: it is one of the most-depended-on JavaScript packages in existence, maintained largely by a single person under significant financial strain. If you type npm core-js into a dependency audit, you will usually find it not because you added it, but because your build toolchain — Babel, a polyfill preset, a framework — pulled it in transitively. That near-universal, mostly invisible presence is exactly what makes it worth understanding.

What core-js is and why it is everywhere

core-js is a modular standard-library polyfill for JavaScript. It backfills ECMAScript features — promises, iterators, Array and String methods, symbols, typed arrays — so that code using modern syntax runs on older engines. Babel's @babel/preset-env wires it in automatically based on your browser targets, which is why "core js npm" installs show up in projects whose authors never referenced it directly. The npm registry lists tens of thousands of dependent projects, and the package has been downloaded billions of times over its lifetime.

The current major line is core-js 3, which is modular: you can import only the polyfills you need rather than the whole library. That modularity matters for bundle size and, indirectly, for security, because a smaller included surface is a smaller thing to reason about.

The postinstall episode

The security story people remember about core-js is the postinstall message. Maintainer Denis Pushkarev added a console message during installation — including a funding link — to seek support for a project he was maintaining largely for free. It generated real friction: npm had moved to discourage advertising output in install scripts, and the messages cluttered CI logs and occasionally interacted badly with strict install setups.

The security lesson here is not that core-js was malicious — it was not. It is that any package with a postinstall (or preinstall) script runs code on your machine the moment npm install executes, before any application logic. A benign funding message and a credential stealer arrive through the exact same mechanism. That is the structural risk of install scripts, and core-js made it visible to a huge audience.

The maintainer funding crisis

The deeper risk is sustainability. Pushkarev has been open about the project's precarious position: minimal donations, funding channels disrupted by financial firms declining to process payments to Russia, and the personal toll of maintaining critical infrastructure alone. He has publicly raised the possibility of stepping back or changing the license.

For anyone consuming core-js, this is a supply-chain risk in the truest sense. A single, under-resourced maintainer of a package in billions of dependency trees is a concentration of both technical and human risk. History shows how these situations can turn: the event-stream incident began when a burned-out maintainer handed a popular package to an unknown volunteer who then added malicious code. core-js is not that story, but the preconditions — high reach, thin support — are ones worth taking seriously rather than ignoring because the package "just works."

Concrete security practices for core-js

You do not remove core-js; you depend on it whether you like it or not. You manage it. The practices that matter:

  • Run installs with scripts disabled where you can. npm install --ignore-scripts in CI and production builds neutralizes the entire install-script attack surface, then maintain a small allowlist for packages that genuinely need to build native code.
  • Pin exact versions and commit a lockfile. Use npm ci in CI so a compromised or unexpected republish cannot silently swap the tarball behind a version string you already trust.
  • Know your version. Because Babel controls which core-js version gets pulled in, an outdated @babel/preset-env config can leave you on an older core-js than you expect. Audit the resolved version with npm ls core-js.
  • Scan the transitive graph. Since you rarely add core-js directly, only a tool that walks the full dependency tree will surface issues in it. An SCA tool such as Safeguard can flag risk in transitively pulled packages like core-js even though nothing in your package.json names them.

Reducing your exposure

Beyond hygiene, you can shrink how much you rely on the polyfill at all. If your browser support matrix has moved forward — and for many teams it has — you may be shipping polyfills for engines you no longer target. Review your browserslist configuration; tightening it lets @babel/preset-env include fewer core-js modules, which reduces both bundle size and the amount of third-party code executing in production. For truly modern-only apps, you may find you can drop the polyfill path entirely.

None of this is core-js-specific fear. It is the standard posture for any single-maintainer package sitting deep in your build. The reason core-js earns a dedicated review is simply reach: when a dependency is in nearly every JavaScript project, the cost of ignoring its risk profile scales with it.

FAQ

Is core-js on npm safe to use?

core-js itself is not known to be malicious and remains actively released in its version 3 line. The real risks are its postinstall script behavior (shared by all packages with install hooks) and its sustainability, given it is maintained largely by one financially strained developer. Manage it with lockfile pinning, script controls, and dependency scanning.

Why is core-js in my project if I never installed it?

Build tooling pulls it in transitively. Babel's @babel/preset-env adds core-js polyfills based on your browser targets, so it appears in projects that never reference it directly. Run npm ls core-js to see what pulled it in.

What was the core-js postinstall controversy?

The maintainer added a console message with a funding link during installation to seek financial support. It caused friction with npm's stance on install-script advertising and cluttered CI logs. The security takeaway is that install scripts run arbitrary code before your app does, so they deserve scrutiny.

How do I reduce my dependency on core-js?

Tighten your browserslist configuration so Babel includes fewer polyfills for engines you no longer support, and for modern-only applications consider dropping the polyfill path entirely. Also pin the version and audit the resolved core-js through your Babel preset config.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.