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 🙏

© 2026 – Pkg Stats / Ryan Hefner

sharjeenux

v1.0.1

Published

A modular, headless Buildroot Linux VM controlled from JavaScript. Install language runtimes as plugins: @sharjeenux/node, @sharjeenux/python, @sharjeenux/java.

Readme

Sharjeenux

Sharjeenux is a headless Buildroot Linux VM that runs through v86 and is controlled from Node.js. The base package contains Linux, BusyBox, networking, Git, curl, wget, OpenSSL, and archive tools. Language runtimes are separate npm packages, so applications install only what they need.

Packages

| Package | Guest tools | | --- | --- | | sharjeenux | Base Linux, shell, Git, curl, wget, OpenSSL, zip/unzip, tar, gzip, bzip2, xz | | @sharjeenux/node | Node.js 20.20.2, npm, npx, Corepack, TypeScript 6.0.3 | | @sharjeenux/python | Python 3.12.13 and pip 25.2 | | @sharjeenux/java | OpenJDK 21.0.11 and Apache Maven 3.9.16 |

sharjeenux/node cannot be a separately installed npm package. In npm, a slash denotes a scoped package only when the name begins with @. The separately publishable form is therefore @sharjeenux/node, matching packages such as @langchain/ollama.

Install

Install the base VM by itself:

npm install sharjeenux

Add one runtime:

npm install sharjeenux @sharjeenux/node
npm install sharjeenux @sharjeenux/python
npm install sharjeenux @sharjeenux/java

Or install all runtimes:

npm install sharjeenux @sharjeenux/node @sharjeenux/python @sharjeenux/java

The runtime packages declare sharjeenux as a peer dependency. Installing the base explicitly keeps the intended version visible in your package.json.

Quick start

import { initialize, send, shutdown } from "sharjeenux";

await initialize();
console.log(await send("uname -a"));
console.log(await send("git --version"));
await shutdown();

Installed runtime packages are detected from the nearest package.json:

import { initialize, exec, shutdown } from "sharjeenux";

await initialize();

console.log((await exec("node -e 'console.log(6 * 7)'" )).output);
console.log((await exec("python3 -c 'print(6 * 7)'" )).output);
console.log((await exec("java --version")).output);

await shutdown();

CommonJS is supported:

const { initialize, send, shutdown } = require("sharjeenux");

await initialize();
console.log(await send("pwd"));
await shutdown();

Selecting plugins explicitly

Automatic detection reads dependencies, optional dependencies, and development dependencies from the nearest package.json. Explicit selection is useful in monorepos or when the process starts from an unusual working directory:

import { create } from "sharjeenux";

const vm = create({
  plugins: ["@sharjeenux/node", "@sharjeenux/python"],
});

await vm.initialize();
console.log(await vm.send("node --version"));
await vm.shutdown();

A missing or invalid requested plugin rejects initialization with an error. It does not silently boot without the requested runtime.

API

initialize(options?)

Boots the default VM and returns it. Repeated calls return the same instance.

const vm = await initialize({
  memoryMB: 2048,
  bootTimeoutMs: 180_000,
  commandTimeoutMs: 1_800_000,
  networking: true,
  networkRelayUrl: "fetch",
  verifyAssets: true,
  plugins: [],
});

memoryMB must be a power of two and at least 128. An empty plugins array still enables dependency auto-detection.

send(command, options?)

Runs a command and returns its output string:

const output = await send("ls -la");

exec(command, options?)

Returns command details without throwing for a nonzero exit code:

const result = await exec("test -f package.json");
console.log(result.output, result.exitCode, result.durationMs);

Both methods support streaming, cancellation, timeouts, and interactive echo:

await vm.send("npm install", {
  timeoutMs: 600_000,
  onOutput: chunk => process.stdout.write(chunk),
  signal: abortController.signal,
});

spawn(command, options?)

Use spawn() for a development server or any command that does not exit by itself:

const server = vm.spawn("npm run dev -- --host 0.0.0.0", {
  timeoutMs: 0,
  onOutput: chunk => process.stdout.write(chunk),
});

server.write("input\n");
server.kill();
await server.exit;

shutdown()

Destroys the default VM and releases its resources.

For independent VMs, use create(options) and call methods on the returned instance.

Package managers

The language packages provide their normal package managers:

await vm.send("npm install is-number");       // @sharjeenux/node
await vm.send("pip3 install requests");      // @sharjeenux/python
await vm.send("mvn --version");              // @sharjeenux/java

Buildroot has no compatible apt, apk, or dnf repository. Native system packages must be added to the Buildroot configuration and rebuilt. Pure JavaScript and pure-Python dependencies are the safest choices; native npm or Python extensions are not guaranteed because the guest does not ship an on-target C/C++ compiler toolchain.

Networking and ports

The default fetch transport supports outbound HTTP. Sharjeenux configures npm to use it. Direct guest TCP/TLS traffic, including many HTTPS Git, pip, Maven, curl, and wget requests, requires a trusted Wisp relay:

await initialize({
  networkRelayUrl: "wisps://your-relay.example",
});

Set networking: false for an offline VM. Sharjeenux does not map listening ports from the guest to the host, browser, or public network.

How the packages combine

Each npm package contains a compressed newc initramfs layer represented as Base64 text chunks of at most 1 KiB. Sharjeenux verifies and decodes the base layer and each installed runtime layer, concatenates them, and passes the result to Linux as one external initramfs. Linux unpacks the archives in order into a single in-memory root filesystem.

Decoded assets are cached under the host temporary directory by SHA-256. The first boot opens many small files; later boots reuse the verified cache.

Runtime constraints

Sharjeenux requires Node.js 20.6 or newer, WebAssembly support, a writable host temporary directory, and enough memory for the configured guest plus emulator overhead. It is a Node.js package, not a browser or edge-runtime package.

It emulates a complete 32-bit x86 computer and is materially slower than native containers or WebContainers. Streaming output makes long operations observable but does not remove the emulation cost.

Creating a third-party runtime layer

A plugin package must contain:

  • plugin.json with format: 1 and type: "sharjeenux-initramfs";
  • assets/manifest.json describing an image named plugin;
  • assets/chunks/plugin/... containing the Base64 chunks; and
  • a package name beginning with @sharjeenux/ or sharjeenux-.

Pass third-party package names through plugins if they are not direct project dependencies. A plugin is executable code inside the guest; install only packages you trust.

Licensing and corresponding source

The JavaScript wrapper is MIT-licensed. The VM layers contain third-party components under their own licenses, including GPL and LGPL components. See THIRD_PARTY_NOTICES.md, SOURCE_OFFER.md, and compliance/ in the base package. Runtime packages repeat the notice and source-offer files so each binary package carries the relevant distribution information.

Release artifacts must be shipped with the matching corresponding-source archive identified by compliance/README.md. The compliance files are engineering aids, not legal advice.