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

jsilnet

v0.2.0

Published

Node.js and browser ECMA-335 / CLI assembly reader and writer

Readme

jsILNET

jsILNET is a JavaScript library for inspecting and rewriting .NET assemblies. It reads PE/CLI formats directly and does not require a .NET runtime. The package provides a synchronous Node.js API and a Promise-based browser API backed by a Web Worker.

Requirements

  • Node.js 20 or later
  • ECMAScript modules
  • Web Workers for the browser entry point (jsilnet/browser)

Install

npm install jsilnet

Quick start

Read an assembly, inspect its metadata, and write an unchanged round trip:

import { readFile, writeFile } from "node:fs/promises";
import { parseAssembly } from "jsilnet";

const input = new Uint8Array(await readFile("input.dll"));
const assembly = parseAssembly(input);

console.log(`Types: ${assembly.types.length}`);
console.log(`Methods: ${assembly.methods.length}`);

await writeFile("roundtrip.dll", assembly.toBuffer());

Example: edit an existing IL operand

This example updates an existing ldc.i4.s operand in a method named Answer and writes the rewritten assembly:

import { readFile, writeFile } from "node:fs/promises";
import { parseAssembly } from "jsilnet";

const assembly = parseAssembly(new Uint8Array(await readFile("input.dll")));
const method = assembly.methods.find((item) => item.name === "Answer");
if (!method) throw new Error("Method Answer was not found");

const instruction = assembly
  .getInstructions(method.rid)
  .find((item) => item.opcode.name === "ldc.i4.s");
if (!instruction) throw new Error("No ldc.i4.s instruction was found");

assembly.setInstructionOperand(method.rid, instruction.offset, 43);
await writeFile("output.dll", assembly.toBuffer());

Edits are validated against the supported input profile; unsupported or unsafe rewrites fail explicitly. See the Current capabilities and API surface references for supported features, APIs, and limitations.

Browser usage

In a browser application using a package-aware bundler with module Worker support, import the separate browser entry point:

import { parseAssembly } from "jsilnet/browser";

async function roundTripFile(file) {
  const assembly = await parseAssembly(file); // File and Blob inputs are supported.
  try {
    const state = await assembly.getState();
    console.log(`Assembly modified: ${state.modified}`);
    const bytes = await assembly.serialize();
    return new Blob([bytes], { type: "application/octet-stream" });
  } finally {
    assembly.dispose();
  }
}

The browser API is Promise-based and runs parsing, editing, and serialization in a Web Worker; the default Node.js entry point remains synchronous. Assembly methods must be awaited, getState() returns a snapshot, and serialize() returns a Uint8Array. Resolver callbacks such as resolveEnum and resolveType may be synchronous or asynchronous. Calling dispose() terminates the Worker and releases its Assembly state.

parseAssembly also accepts Uint8Array and ArrayBuffer. For full-buffer byte inputs, { transferInput: true } transfers the input to the Worker and detaches it from the caller; subarray views are copied.

Live Demo

The browser-only demo in live-demo/ inspects and patches .NET assemblies without uploading them. Build it with npm run build --prefix live-demo, then serve live-demo/dist/ from any static web host. See live-demo/README.md for local preview instructions.

Documentation

Development

npm install
npm test
npm run check
npm run check:browser