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

@lojhan/slab

v2.1.0

Published

High-performance SharedArrayBuffer structs for Node.js, Deno, Bun and Browser

Readme

@lojhan/slab

CI npm License: MIT

High-performance SharedArrayBuffer structs for Node.js, Deno, Bun, and Browsers.

slab allows you to create structured data layouts (structs) backed by SharedArrayBuffer, enabling true zero-copy data sharing between JavaScript workers and the main thread.

It is designed for high-performance applications like game engines, simulations, and data processing pipelines where minimizing garbage collection and transfer overhead is critical.

Features

  • Zero-Copy Transfer: Pass complex data structures to workers instantly (12x faster than postMessage).
  • Parallel Processing: Utilize all CPU cores efficiently without serialization overhead.
  • Typed Structs: Define C-like structs with strictly typed fields (Int32, Float64, Strings, etc.).
  • Memory Efficient: Uses a single SharedArrayBuffer slab for thousands of objects, reducing GC pressure.
  • Flyweight Views: Avoid creating thousands of JS objects; reuse a single "view" to iterate over millions of entities.
  • Concurrency Primitives: Built-in support for Atomic operations and Mutex locking.
  • Dual Layout Support: Switch between AoS (Array of Structures) and SoA (Structure of Arrays) with a single config flag.
  • Sparse Sets: Includes a high-performance Sparse Set implementation for Entity Component Systems (ECS).

Installation

npm install @lojhan/slab

⚡ Quick Start

1. Define a Schema

import { schema, StructCollection } from "@lojhan/slab";

// Define a "Player" struct
const PlayerSchema = {
    id: schema.uint32(),
    x: schema.float32(),
    y: schema.float32(),
    health: schema.uint8(),
    name: schema.string(16) // Fixed-size string (16 bytes)
};

// Create a collection that holds 1,000 players
const players = new StructCollection(PlayerSchema, 1000);

// Access a player at index 0
const p1 = players.get(0);
p1.id = 1;
p1.x = 10.5;
p1.y = 20.0;
p1.health = 100;
p1.name = "Hero";

console.log(p1.name); // "Hero"
console.log(p1.x);    // 10.5

2. Zero-Copy Worker Transfer

The real power of slab comes when using Workers. Instead of copying data, you share the underlying buffer.

Main Thread:

import { Worker } from "node:worker_threads";
import { StructCollection } from "@lojhan/slab";
import { PlayerSchema } from "./schema"; 

const players = new StructCollection(PlayerSchema, 10000);
const worker = new Worker("./worker.js");

// Send the SharedArrayBuffer to the worker (Zero Copy!)
worker.postMessage(players.buffer);

Worker Thread:

import { parentPort } from "node:worker_threads";
import { StructCollection } from "@lojhan/slab";
import { PlayerSchema } from "./schema";

parentPort.on("message", (buffer) => {
    // Reconstruct the collection from the shared buffer
    const players = new StructCollection(PlayerSchema, 10000, buffer);
    
    // Create a reusable view for iteration (Flyweight Pattern)
    const view = players.createView();
    
    for (let i = 0; i < 10000; i++) {
        view.use(i); // Point the view to the i-th struct
        view.x += 1.0; // Update shared memory directly
    }
});

Benchmarks

Benchmarks run on Apple M1 (macOS).

| Benchmark | Result | Improvement | |-----------|--------|-------------| | Zero-Copy Transfer | Struct vs Native Serialized | 11.88x Faster | | Allocation | Struct vs Native Objects | 2.71x Faster | | Parallel Processing | Struct vs Native Workers | 2.61x Faster | | Sparse Set Lookup | Slab vs Native Map | 1.90x Faster |

Note: Single-threaded reads/writes are generally slower than native V8 objects due to the overhead of DataView accessors. This library is optimized for multi-threaded/shared-memory scenarios.

API Reference

Schemas

Supported types:

  • int8, uint8, int16, uint16, int32, uint32
  • float32, float64
  • boolean
  • string(length) (UTF-8)
  • mutex (32-bit lock)

Collections

  • new StructCollection(schema, capacity, buffer?, options?): Create a new collection.
  • collection.get(index): Get a view for a specific index.
  • collection.createView(): Get a reusable flyweight view.
  • collection.buffer: The underlying SharedArrayBuffer.

Thread Safety

For safe concurrent access, use the mutex type and locking methods:

const Data = {
    value: schema.int32(),
    mutex: schema.mutex()
};
const items = new StructCollection(Data, 10);
const item = items.get(0);

// Blocking lock
item.lockMutex(); 
item.value += 1;
item.unlockMutex();

// Non-blocking try-lock
if (item.tryLockMutex()) {
    item.value += 1;
    item.unlockMutex();
}

License

MIT © Vinicius Lojhan