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

@scriptc/threads

v0.3.0

Published

Zero-copy publication of immutable object graphs to worker threads (scriptc), with a deep-freezing Node.js implementation

Downloads

581

Readme

@scriptc/threads

Zero-copy sharing of immutable object graphs between worker threads in scriptc builds, with a Node.js implementation that gives the same graphs the same immutability.

import { Worker, isMainThread, workerData } from "node:worker_threads";
import { publish, sharesPublishedGraphs } from "@scriptc/threads";

if (isMainThread) {
  const program = publish(buildProgram()); // immutable from here on
  new Worker(new URL(import.meta.url), { workerData: { program } });
} else {
  const program = publish((workerData as { program: Program }).program);
  check(program);
}

Contract

publish(value) returns value after making it and everything it reaches immutable.

  • Publishable: primitives other than symbols, plain objects, arrays, class instances, Map and Set. Anything else that is actually reached (functions, symbols, accessor properties, Date, RegExp, Error, Promise, typed arrays and other built-in objects) makes publish throw a TypeError (Cannot publish a function, Cannot publish a Date object, ...) and leaves the whole graph unchanged: both implementations validate the graph before changing anything.
  • Writes into a published graph throw Node's frozen-object TypeErrors: Cannot assign to read only property 'x' of object '#<Point>', Cannot add property 3, object is not extensible, Cannot delete property '2' of [object Array], and so on. Published Maps and Sets reject set, add, delete and clear with Cannot modify a published Map (or Set).
  • publish is idempotent; publishing an already published graph is cheap.

In scriptc builds a published graph is also immortal: it is never reference counted, collected or freed again, and postMessage and workerData deliver it to other threads by reference (sharesPublishedGraphs is true). Node.js clones what it posts (sharesPublishedGraphs is false). Programs that behave identically under both follow three rules:

  1. A receiver calls publish on what it receives. In scriptc this is a no-op; in Node.js it freezes the clone, so writes fail the same way.
  2. A receiver does not depend on prototypes. scriptc delivers the same class instances, with their methods and instanceof relations; Node's structured clone delivers plain objects. Error messages that name the receiving object's class differ accordingly (#<Point> in scriptc, #<Object> in Node.js).
  3. Identity is not compared across messages. Two posts of one published graph arrive as the same object in scriptc and as two clones in Node.js.

scriptc specifics

  • Publication walks the graph once (compiler-generated walkers per static type) and marks every object immortal. Static types over-approximate what a graph holds, so an unpublishable type reachable from the root's type is only refused if a value of it is actually present.
  • Stores into the static types a program publishes carry a guard (one load and branch). In a store o.x = f(), Node evaluates f() before the write fails; scriptc does too, except for writes into union-typed class fields and for Map/Set/array mutator methods, where the guard runs before the arguments are evaluated.
  • Private fields (#x) of published objects cannot be written either (Node.js allows writing private fields of frozen objects).
  • Published objects must not be written by any thread; scriptc enforces this for every store the compiler emits.