OpenJS has formed a neutral industry group called the Package Metadata Interoperability Collab Space that is working to “iterate on the informal standardization of package.json and improve the interoperability of JavaScript package metadata for application developers.”
The group was announced in a post titled “Why Should You Care About Package Metadata Interoperability?” Answering its own question, the foundation stated that standards result in good tools:
Imagine if there was a more clear and all encompassing definition, improved regularly and with wide input, that everyone could base their tooling off of. This informal standard would not depend on Node.js and npm but be set up for the broad community to use.
The announcement emphasizes that the foundation is not proposing a formal standard but rather “an agreed upon framework for technical considerations.” Part of OpenJS’ mission is to promote the widespread adoption and continued development of key JavaScript and web solutions and related technologies. It also exists to facilitate collaboration within the JavaScript development community, among other functions.
Package.json has become the de facto standard for configuring JavaScript projects, functioning as a manifest that outlines metadata for a project, along with its dependencies and configurations. Its history is inextricably intertwined with the evolution of Node.js and its package ecosystem, but OpenJS highlighted that this group aims to be inclusive of the diverse needs of those using alternative JavaScript runtimes:
Tooling is currently being developed in Node.js since that is what current members are most familiar with and will enable us to publish and iterate quickly. We are completely open to additional tooling being developed in other JavaScript runtimes and languages.
OpenJS doubling down on improving package.json is an interesting development against the backdrop of the Deno team getting ready to launch JSR, a new package registry. Deno co-founder and Node.js creator Ryan Dahl identified package.json as a regret in the first presentation announcing Deno in 2018.
“Package.json is like the life blood of JavaScript at this point,” Dahl said. “But, you know, at some point, it wasn't, and Isaac of npm fame more or less defined it, although there might have been some sort of specification, and I largely sanctioned it, and made it popular by allowing require() in Node semantics to look into package.json and look through files.”
During his presentation, Dahl expressed concerns about the implications of integrating package.json into Node.js and npm, highlighting issues like the introduction of modules as directories, the perceived clutter from non-essential metadata, and the inefficiency of local dependency management leading to bloated projects:
This makes package.json necessary for Node programs where it was not before, and then ultimately, I included npm into Node, which made npm the standard Node distribution service. Linking to a package requires a lot of systems here, a lot of components. The problem I have with [package.json] is that it gives this rise to a concept of a module as this directory of files, where that wasn't really a concept before.
Package JSON has all this unnecessary noise in it - like license, repository. Why am I filling this out? I feel like a bookkeeper. This is unnecessary stuff to do when all I'm trying to do is link to a library. Of course, Node modules get very big because it kind of has this vendoring by default semantics were modules are installed locally into your project folder, and if you have multiple projects, you have multiple node module folders and it gets big. This was my idea. I regret it.
Because of Dahl’s well-documented convictions that package.json was a mistake, Deno users were surprised when the project added support for package.json in March 2023, in order to enhance Node and npm compatibility. Dahl assured users that Deno is still intent on “forging a path distinct from Node.”
This compatibility for package.json allows developers to run existing Node projects directly in Deno, but it was designated as “backwards compatibility” when it was introduced, an important distinction.
“Backwards compatibility doesn’t mean the JavaScript ecosystem cannot evolve and improve,” Dahl said.
“Whether using modern import map workflows or Node.js package.json workflows, Deno aims to be a reliable tool developers reach for to accelerate their work. JavaScript, the world’s default programming language, deserves this continued effort to improve its ecosystem and tooling.”
(It’s worth noting that Deno supports a deno.json configuration file but it functions differently, allowing developers to customize the built-in TypeScript compiler, formatter, and linter. In contrast to package.json, deno.json is primarily used for configuration purposes. It also acts as an import map to resolve bare specifiers like "react" or "lodash”. This may become more of a point of fragmentation if the new JSR registry gains wider adoption as well since it is supporting jsr.json as an alternative file as well.)
It appears that OpenJS is solely focusing this new group’s collaboration efforts on package.json, but this may not directly benefit those who are operating at the fringes while trying to innovate in this space. It will be interesting to see how the group can deliver value to diverse ecosystem stakeholders, who have all but scrapped the concept of package.json but still intend to launch a new package registry.
The early contributors are currently researching existing practices and tools to index their strengths and weaknesses, and are building tooling around the research. Their efforts are aimed at supporting the diverse JavaScript ecosystem:
Ultimately, this means that everyone is chasing a moving target of the npm informal standard. Luckily, npm is a good actor with good intentions. But it's at best an inefficient way for tools to improve and support a diverse ecosystem. Tool makers are forced to take liberties to make their tools operate but still try to be compatible.
It means everyone is striving towards an undefined standard, and the target can shift unexpectedly.
The package.json research GitHub repository was created for producing a directory of markdown files containing the analysis for one or more top-level package.json properties, with the following guidelines:
- The file, package-json.md, contains a property research index.
- Research should primarily focus on a property's existing rule-set and use-cases. Details should be presented in such a way to not infer bias to any single tool; however, since many tools share the same behavior, those details can be presented as fact.
- For example, the dependencies property has a number of ways a dependency can be specified. From using SemVer, workspace syntax, or even specifying a git link, many package manager tools will resolve the value in a similar way (though the lockfile output may be unique).
- Research should accurately and clearly declare when it is presenting tool-specific behavior about a certain package.json property.
The team is also working on creating package scaffolding and welcomes contributors on these projects.
Next Steps#
The collaboration group has just started on their efforts and encourage prospective contributors to join their monthly meetings, which happen on the first Tuesday of each month.
Even though OpenJS is not formally standardizing package metadata, their projects have the potential to advance shared best practices, and establish common data structures and well-defined attributes that anyone can use. This facilitates packages from different sources being effectively utilized together.
While formal standards are slower to evolve and may not always adapt to an ecosystem as fast-paced as Node, this agile, community-driven approach allows interested stakeholders to improve metadata practices without additional bureaucratic constraints.