nolyfill swaps dead Node 4 polyfills for the native functions
Speed up your package installation process, reduce your disk usage, and extend the lifespan of your precious SSD.
At a glance
- What is it?
- nolyfill is a CLI that scans a project's dependencies for polyfills that exist natively in modern Node and replaces them with tiny stand-ins, which shrinks node_modules and speeds up installs. The problem it solves is upstream packages still shipping Node 4 support, and the tool works by rewriting your package.json overrides.
- Who is it for?
- Adopt nolyfill if your node_modules is full of polyfills that modern Node already provides, since replacing them shrinks the install and the runtime cost. Do not adopt it if you run Node below 12.4.0 or target an environment without full ES2019 support, because the replacements assume the native implementations exist.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 28 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is upstream packages that never dropped Node 4
The reason section is specific about who is responsible. While you are embracing the latest features and security fixes by installing the latest Node.js LTS, packages like `eslint-plugin-import`, `eslint-plugin-jsx-a11y`, `eslint-plugin-react`, and many others maintained by ljharb are still trying to support the long-dead Node.js 4 by adding tons of polyfills. Those polyfills inflate the node_modules size, waste disk space and slow down the `npm i`, `yarn` and `pnpm i` commands. And the README adds the part that is worse than the size, that ljharb uses the polyfill implementation even when a native version is available in the environment, which makes the code run slower. The polyfill is not just dead weight, it shadows the faster native path.
The fix is a package manager override, not a patch
nolyfill is a set of tiny packages, one per polyfill, that are used to replace the originals through the package manager's override mechanism rather than by editing files in node_modules. The root package manifest shows the shape of that: it is a pnpm workspace whose `pnpm.overrides` block maps the original package names, such as `abab`, `array-buffer-byte-length`, `array-flatten`, `array-includes`, `array.from`, `array.of` and the `array.prototype.*` family, onto the `@nolyfill/` versions of the same name. The project is pinned to pnpm 9.12.1, and the workspace holds the `packages/` directory with the data packages, a `patches/` directory, and a `turbo.json` for the task runner. The effect is that a package depending on `array-includes` gets the native implementation instead, without the depending package changing anything.
The CLI lists first and replaces second
The tool is a two step command, and the order is deliberate. Run it without a subcommand in your project directory and it finds and lists all the redundant polyfills:
npx nolyfill
# You can also specify the path to your project directory:
npx nolyfill ~/projects/my-projectThen you use the `install` command to replace them:
npx nolyfill install
# Or in the specified directory:
npx nolyfill install ~/projects/my-projectSo the audit step is a dry run, and nothing in your dependency tree changes until you ask for it. The CLI options are short. The `--pm` flag overrides the package manager detection, which by default tries to detect the preferred package manager of the project automatically, with `npm`, `yarn`, `pnpm` and `auto` as the supported values. There is `-d` for debug output with full error messages and stacks, `-v` for the version and `-h` for help.
Two clear cases where you should not use it
The README has a section on when not to use the tool, and it is short enough to be unambiguous. The first is if your Node.js version is below 12.4.0, because the whole premise is that the native implementations are there. The second is if you are targeting an environment that does not have full ES2019 support, and here the README recommends a different tool entirely: you should really use core-js or core-js-pure instead, because it is significantly faster. That is worth noticing. nolyfill is not a general polyfill solution, it is a way to remove polyfills that are not needed, and if you do need polyfills, the recommendation is the mainstream library rather than this set of single-function stand-ins.
Adding a new polyfill is a codegen task
The development section describes how a new replacement is added, and it shows the structure of the project. You add the definition in `packages/data/es-shim-like/src/` or `packages/data/single-file/src/`, and in a `create.ts` file, and then you run `npm run codegen`. The codegen script is a Node invocation with the swc node register, so the generation is a TypeScript program rather than a template. The README also warns about the codegen output, that rarely used packages will not be added, and that some packages which are just sub-dependencies will not be added either. The two data directories correspond to two kinds of replacement, one for packages that mirror an ES shim API and one for single function packages. The contribution guidance has a rule of thumb that is easy to remember: when an install prints a message about using the platform's native version, and it is available on Node.js 12 or below, it is time to nolyfill it.
The monorepo tooling and the release line
The build is a turbo pipeline over the workspace, with the root scripts running the tasks, the analysis variant setting an ANALYZE flag, and the release using bumpp with a message and a tag template, driven by a `bump.config.ts` file at the root. The build itself is Rollup with the swc plugin and a plugin for generating declaration files, and the package is compiled with tsc into a separate build configuration. Linting is run through a custom ESLint configuration with a custom formatter, and the shared ESLint and TypeScript configurations live in the workspace as packages. The root package is private, named `nolyfill-monorepo`, at version 1.0.44, and the Node engine requirement is 16.8.0 or newer, which is more permissive than the 12.4.0 floor mentioned for the replacements themselves, because the CLI has to run on older Node than the projects it rewrites. The licence is MIT, with the project authored and maintained by Sukka.
Editorial conclusion
Adopt nolyfill if your node_modules is full of polyfills that modern Node already provides, since replacing them shrinks the install and the runtime cost. Do not adopt it if you run Node below 12.4.0 or target an environment without full ES2019 support, because the replacements assume the native implementations exist. Verify first which polyfills the tool would replace by running it without the install subcommand, since it lists them before changing anything, and check the overrides it writes into your package.json against the package manager you actually use.
Frequently asked questions
What does nolyfill do?
It finds polyfills in your dependencies that are already available natively in modern Node.js and replaces them with very small alternatives, which reduces the size of node_modules, speeds up installation and lets the faster native implementation run instead of the polyfill.
How do I use the nolyfill CLI?
Run `npx nolyfill` to list the redundant polyfills in the project, then `npx nolyfill install` to replace them. You can pass a project directory path as an argument, and the `--pm` option overrides package manager detection between npm, yarn, pnpm and the automatic default.
When should I not use nolyfill?
Not if your Node.js version is below 12.4.0, and not if you are targeting an environment without full ES2019 support, where the README recommends core-js or core-js-pure instead because it is significantly faster.
How does nolyfill replace the polyfills without patching packages?
It uses the package manager's override mechanism, mapping the original package names onto the small `@nolyfill/` versions of the same name, so the depending packages do not have to change anything.
What licence is nolyfill released under?
The MIT licence, with the licence file in the repository root and the project authored and maintained by Sukka. The last push to the master branch was on 2026-09-25, and the repository has no GitHub releases.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sukkaw-nolyfill)Was this useful?