Historically, NPM has had a number of issues that affected the entire ecosystem one way or the other. I tend to believe most of those issues arise from the fundamental design flaws of NPM and are not as easily solved.
In this document, I propose an alternative to the NPM registry. Let's call it a "Proper Package Registry", or PPR for short. This alternative aimes to solve the long-standing issues with NPM, such as name squatting, package unpublishing, versioning, as well as add a few points concerning developer experience, which is close to non-existing when using NPM as a package author.
PPR ships with a CLI that offers extensive tools to validate the package you are about to publish. This is completely missing from NPM and has been in the top of my painpoints list for all the years I've been publishing packages.
The package validation tooling helps with the following:
- Validates
package.json
for missing required fields, likename
,version
, and at least one entrypoint (e.g.main
). - Ensures that the values for the entrypoints reference existing files before publishing. Forgot to run a build command? PPR has got your back, pal.
- Validates the
exports
field inpackage.json
, if present. The conditional exports has been a huge pain to work with. The publishing tool should be responsible at least to some extent to ease that pain for the authors. - Validated the installed dependencies to not be symlinked. It's not uncommon to symlink things when developing. When publishing, however, everything must be as-is from the registry. Your local links are removed/stashes for the time-being.
- Recommends sensible community default, such as
README
andLICENSE
files, the inclusion ofrepository
andhomepage
inpackage.json
, and a clearauthor
field. Even as little as checking whether your static assets aren't broken inREADME
can be a nice experience boost.
- All packages are scoped by default. If you are
octocat
on GitHub, all your packages are published under@octocat/<PACKAGE_NAME>
on PPR. No name-squatting. You can only publish packages to the GitHub scopes you own, which allows you to publish packages for your organization as well. - You must provide an explicit tag for each publish. No more accidental publishing of beta releases as
latest
. - Ideally, an interactive prompt for publishing would be nice. Suggest the next version based on the commits (assumes you're using a commit naming convention that allows that), suggests which tags you want to publish, etc.
- Unpublishing. I don't have a concrete suggestion here. Unpublishing is a difficult problem to solve. What I can say is that it's the wrong control flow when the management of your package is decided by how others use it. Ideally, you should be able to unpublish anything at any time but that raises a few moral and practical concerns as history shows.
- Ban the
postinstall
hook. It's a security vulnerability and it's already discouraged. If you need to perform computations on the user's machine, such as assemble a platform-dependent binary, do that on your machine and reference those binaries inexports
or similar to be picked up on the right platform.