Thoughts on JSR This past month saw the public release of the JavaScript Registry (JSR), a direct competitor to npm. The folks behind JSR are the same folks behind Deno, a direct competitor to Node.js. While it may not be surprising that a Node.js competitor would also create an npm competitor, Deno actually started with a theory that the JavaScript community didn’t need npm or any other package manager. In fact, in Ryan Dahl’s original talk announcing Deno, he explicitly mentioned npm as a regret and believed that HTTP module specifiers were a better solution. Fast forward five years and Ryan changed his tune, at first adopting npm compatibility for Deno and then announcing JSR as an alternative to npm. My initial reaction to this news was, “oh boy, here we go again.” We’ve been down this road before. GitHub, the current owner of npm, launched its own npm-compatible package registry in 2019. GitHub’s package registry featured deep integration with GitHub repositories, simplifying the process of publishing a package directly from a GitHub repo. Ultimately, the GitHub npm package registry never gained traction and GitHub ended up purchasing npm, Inc. and took over the formal administration of npm. So how is JSR different? Instead of taking the GitHub route of full npm compatibility, JSR reimagines what a package registry should be in 2024. JSR wants to be the only package manager you need, and just like Deno, isn’t relying on old paradigms and ways of doing things. If JSR succeeds, it will be because of how different it is from npm as opposed to the GitHub npm package registry, which would only succeed if it worked the same as npm. Some of the key features that make JSR intriguing: Deep GitHub integration. JSR leans into GitHub’s popularity by using it for both user and package credentials. To get started with JSR, you need a GitHub account, and that account is tied to your JSR account. Further, any package you create must be linked to a GitHub repository – not by placing the GitHub URL in a package.json file, but rather, by linking the package through the JSR website. For CI publishing, your package can only be published directly from the linked GitHub repository, automatically generating the provenance information that npm only recently added. If you want to publish manually, you’ll be prompted to approve the publish on the JSR website. Cross-runtime compatibility. JSR isn’t just a package manager for Deno, it’s designed to work with Node.js, Bun, and web browsers, as well. That means you don’t need to publish a package to both npm and Deno for your code to be usable on multiple runtimes. A runtime-agnostic jsr package enables publishing and installing JSR packages on any server-side runtime. TypeScript- and ESM- focused. JSR is built for a world where everyone writes ESM modules and most people write in TypeScript. JSR doesn’t support CommonJS in any way, so there are no confusing processes to ensure compatibility. And because JSR treats TypeScript as a first-class citizen, there’s no need to transpile into JavaScript before publishing. JSR stores the TypeScript and will generate JavaScript on-demand when a package is used in a runtime that doesn’t have built-in TypeScript support. That doesn’t mean you can’t publish JavaScript packages, as well. JSR supports JavaScript packages with .d.ts files for maximum compatibility. Git awareness. JSR won’t publish anything listed in your .gitignore file unless you override it in your jsr.json file, saving you from needing to create a second file just for JSR. Also, JSR won’t let you manually publish if the Git repository has uncommitted changes. Having fallen into this trap early on in the days of ESLint, this is an extra safety check I really appreciate. (You can override this check with a command line flag if you really want to publish uncommitted changes, which can happen in a CI process if you are generating some of the file at publish time.) Responsible package name stewardship. One of the complaints about npm is how hands-off they are about package naming. There is a lot of package name squatting on npm and very little recourse should someone squat on a name that you have a right to. Further, because npm package names are case-sensitive, it’s easy for malicious actors to create packages that users might confuse for legitimate ones. JSR solves all of these problems by forcing all package names to be lowercase, explicitly disallowing squatting, and watching over package scopes that might be used by well-known packages. When I first went to register the “@eslint” scope, I was pleasantly surprised to see an error message saying that this scope was reserved and I’d need to contact support to request access. Given all of that, will JSR succeed in overtaking npm? It’s too early to tell. Just like Deno introduced a lot of objective improvements over Node.js, JSR does the same for npm. However, the internet has a history of entrenched, “good enough” technologies outlasting better newcomers through sheer inertia. npm is a technology we’ve been using for 14 years, so we’re aware of all the sharp edges and performance characteristics. JSR is a couple of months old and yet to be really tested in production. However, it is the first significant competitor to npm in a long time, so I’ll grab some popcorn and watch intently. Key Takeaways
Stuff I've Enjoyed This Month📚 Speak Like Churchill, Stand Like Lincoln by James C. Humes 🎬 Container Training by Jérôme Petazzoni 📝 On popover accessibility: what the browser does and doesn't do by Hidde de Vries 📝 Using the Service Worker Static Routing API by Rachel Andrew What I'm Working On🏠 Real Estate: End of year bookkeeping is finally complete. The cost of insurance and property taxes increased tremendously in 2023. One of property, my insurance doubled and the property taxes increased by 33%. Unfortunately, that meant I had to raise rents on several properties to cover those costs. Follow my Instagram for real estate photos. 📝Writing: I wrote a couple of new posts:
💻 humanfs: I continued working on humanfs in the past month, focusing on eliminating more errors. In most cases, humanfs will not throw an ENOENT error, making it a lot easier to use than builtin file system APIs on Node.js, Deno, and Bun. Check it out if you haven't already! 💻 ESLint: ESLint v9.0.0-rc.0 has been released! This is the first release candidate for v9.0.0, which means the final release is just around the corner. We are still working on a couple of ecosystem changes to support v9.0.0, and when those are complete, the final release will be done. |
A once-per-month newsletter discussing topics important to senior-level software engineers, with a particular focus on frontend technology and leadership.
Thoughts on Chrome That ruling stated that Google had an illegal monopoly on search and excluded competition by paying other browsers to feature Google search as their default search engine. Subsequently, the U.S. Department of Justice requested that a judge force Google to sell off its own browser, Chrome, as well as stop all exclusive search deals (among other concessions). This represents the most significant legal loss for a tech company in the United States since Microsoft was ordered to...
Thoughts on Return-to-Office If you’ve been following tech news in the past month, you’ve likely heard about Amazon’s strict return-to-office policy, which will require employees into the office five days per week beginning in January 2025. The climate for tech workers has changed dramatically over the past three years, and Amazon, along with other companies, now shows no fear of losing employees with strict return-to-office mandates. For the first time in a long time, tech companies aren’t...
Thoughts on Weaponizing Open Source When you think of open source software, you might think of it as a gift from someone to the world. They’ve written something of value, and instead of trying to make money off of it, they’ve posted it online for anyone to use (and potentially make money off of) for free. While many projects start that way (Linux, ESLint, etc.), there’s another way open source comes into being: as a weapon against a company’s competition. Android. Perhaps the best example of...