npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@remax-ide/npm-in-browser

v0.1.4

Published

npm CLI in browser without 3rd party services or blackbox scripts

Downloads

4

Readme

npm-in-browser

Please help spread the initial announcement X post!

Note: This was initially developed for JS Bundle Lab

npm-in-browser is a pure ESM npm package to run npm CLI (e.g "npm install") in browser without any 3rd party service, black box scripts, or heavy full-fledged Node.js emulation layer. It "just" runs npm CLI and things like SharedArrayBuffer are not needed. It's easy to embed in any environments.

This is possible since the official npm registry allows CORS.

This repo includes a build script to compile the original source of npm by providing appropriate shims for Node.js specific things such as process. Since it instantiates this kind of globals for every runNpmCli run, most likely it does not pollute the global environment although there is no strict enforcement.

Probably the best way to use npm-in-browser in production is to run it inside Web Workers although it can run on the main thread just fine. Since we can instantiate fs (e.g. memfs) inside the worker, there is no need to run a dedicated "file system worker" as long as you are just interested in using that fs in the same worker for the subsequent processing such as "running Webpack in browser".

import memfs from "memfs";
import { runNpmCli } from "npm-in-browser";

await runNpmCli(["install", "react", "react-dom"], {
  // Here we use memfs but anything compatible with Node.js fs can be used
  fs: memfs.fs,
  cwd: "/home/web/app",
  stdout: (chunk) => {
    console.log("stdout", chunk);
  },
  stderr: (chunk) => {
    console.log("stderr", chunk);
  },
  timings: {
    start(name) {
      console.log("START: " + name);
    },
    end(name) {
      console.log("END: " + name);
    },
  },
});

// This should print the contents of package.json of react
console.log(
  memfs.fs.readFileSync("/home/web/app/node_modules/react/package.json"),
);

If you just want to play with it without any frontend bundlers, you can import packages from esm.sh like:

<script type="module">
  import memfs from "https://esm.sh/[email protected]";
  import { runNpmCli } from "https://esm.sh/[email protected]";
  ...
</script>

For working examples using bundlers such as Vite, please check out examples directory of this repo. I also created a demo using StackBlitz, which feels weird since StackBlitz itself can do "npm install" by itself via WebContainers.

Note that if you are fine with loading 3rd party non open source code from 3rd party host and there is no concern around commercial licensing, WebContainers or Nodebox can be a better option. Since they use dedicated CDN for their services, loading performance can be better as well. Debugging, profiling, and tuning (customizing) could be easier with npm-in-browser though.

npm-in-browser is distributed as a pure ESM npm package.

Runtime performance

We know that WebContainers / Nodebox are highly optimized in many ways. However, it turned out that both initial boot time and warm start up time is not so bad. You can see it by yourself. Note that the performance of fs is really important here. For example, we found that "just using memfs" is really slow since it falls back to slower polyfill for setImmediate. You should use setImmediate.js as a polyfill. Let us know if there are any easy-to-use high performance fs implementation for browser out-of-the-box.

Benchmarks

You can check out In-browser "npm install" benchmark, where we compare the performance of WebContainers, Nodebox, and npm-in-browser.

Known issues

  • Versioning. Currently npm-in-browser just ships the latest npm.
  • It does not send most of HTTP headers for the npm registry. If specific features of npm require these, it does not work.
  • Running runNpmCli several times leaks some amount of memory. This can be mitigated by running it in Web Workers and terminate them appropriately.
  • Since there is no runtime enforcement for the isolation, running runNpmCli could pollute some globals.
  • The npm registry does not return CORS header appropriately for "404 Not Found" responses (e.g. "https://registry.npmjs.org/abc-xyz-123456"). Because of this, we cannot distinguish general fetch error and "not found" error. https://github.com/naruaway/npm-in-browser/issues/1

License

npm-in-browser is MIT licensed.

As an npm package, it redistributes 3rd party sources under different licenses, which is listed under ./dist/third-party-licenses.json

Please file an issue if you find any potential license violations.