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

@archboard/elk-rs

v0.11.3

Published

ELK layout engine in Rust — elkjs-compatible API with WASM and native Node.js addon (fork of openedges/elk-rs)

Readme

@archboard/elk-rs

ELK layout engine rewritten in Rust — drop-in replacement for elkjs with WASM and native Node.js addon support.

This is a fork of openedges/elk-rs (source), published under the @archboard scope. Besides its npm packaging it fixes these problems in the JS package:

  1. The WASM fallback works on Node.js and Bun when no native addon is installed (upstream loaded the web-target WASM without initialising it).
  2. js/elk-worker.js no longer mistakes Bun's main thread for a Web Worker.
  3. A layout error rejects with an Error carrying ELK's message and prints no Rust panic to stderr; on WASM the message is reported instead of an unreachable trap, and the next layout starts from a fresh instance.
  4. Every export has type declarations, and @archboard/elk-rs/worker.browser is a module Web Worker for bundled browser apps.

and lays graphs out as the elkjs build archboard used does: interactive layouts no longer deadlock and follow an edge's previous bend points, and Java's float arithmetic is computed in double, as GWT compiles it.

Installation

npm install @archboard/elk-rs
# or
bun add @archboard/elk-rs

On supported platforms a native addon is installed through an optional dependency; everywhere else the package falls back to WASM.

| Platform | Package | |---|---| | macOS ARM64 (Apple Silicon) | @archboard/elk-rs-darwin-arm64 | | macOS x64 (Intel) | @archboard/elk-rs-darwin-x64 | | Linux x64 (glibc) | @archboard/elk-rs-linux-x64-gnu | | Linux x64 (musl) | @archboard/elk-rs-linux-x64-musl | | Linux ARM64 (glibc) | @archboard/elk-rs-linux-arm64-gnu | | Windows x64 | @archboard/elk-rs-win32-x64-msvc |

The native addon's layout() runs synchronously on the calling thread (the returned promise is already settled); run it in a Worker to keep a thread free.

Usage

elk-rs provides an elkjs-compatible API. In most cases you can replace elkjs with @archboard/elk-rs directly:

const ELK = require('@archboard/elk-rs');
const elk = new ELK();

const graph = {
  id: 'root',
  layoutOptions: { 'elk.algorithm': 'layered' },
  children: [
    { id: 'n1', width: 30, height: 30 },
    { id: 'n2', width: 30, height: 30 },
  ],
  edges: [
    { id: 'e1', sources: ['n1'], targets: ['n2'] }
  ]
};

elk.layout(graph).then(console.log);

ESM

import ELK from '@archboard/elk-rs';
const elk = new ELK();

Browser

elk-rs works in the browser via WASM. Bundlers that respect the "browser" field in package.json will automatically use the browser entry point.

Web Worker

const ELK = require('@archboard/elk-rs');
const elk = new ELK({
  workerUrl: './node_modules/@archboard/elk-rs/js/elk-worker.js'
});

In Bun, as with elkjs:

import ELK from '@archboard/elk-rs/js/elk-api.js';
const worker = new Worker(import.meta.resolve('@archboard/elk-rs/js/elk-worker.js'));
const elk = new ELK({ workerFactory: () => worker });

Module Web Worker in a bundled browser app

@archboard/elk-rs/worker.browser is an ES module worker with no Node.js dependencies: it instantiates the WASM build, whose binary it references with new URL(..., import.meta.url) so bundlers emit it as an asset, and answers elkjs's worker protocol. With Vite:

import ELK from '@archboard/elk-rs/js/elk-api.js';
import ElkWorker from '@archboard/elk-rs/worker.browser?worker';

const elk = new ELK({ workerFactory: () => new ElkWorker() });

A layout that fails rejects with an Error carrying ELK's message, and the worker replaces its WASM instance before the next layout.

A pool of workers can share one compiled module instead of each compiling the 5.5 MB binary: compile it once on the page and send it to each worker as its first message. A worker that receives no module compiles its own when its first layout arrives.

import ELK from '@archboard/elk-rs/js/elk-api.js';
import ElkWorker from '@archboard/elk-rs/worker.browser?worker';
import wasmUrl from '@archboard/elk-rs/wasm-url';

const module = await WebAssembly.compileStreaming(fetch(wasmUrl));
const createElk = () => new ELK({
  workerFactory: () => {
    const worker = new ElkWorker();
    worker.postMessage({ cmd: 'init', module });
    return worker;
  },
});

API

new ELK(options?)

  • defaultLayoutOptions — default layout options applied to every layout() call
  • workerUrl — URL to the worker script (enables Web Worker mode)
  • workerFactory — custom function to create a Worker instance
  • algorithms — list of algorithm IDs to register (all built-in by default)

elk.layout(graph, options?)

Returns a Promise<LayoutedGraph>. The graph follows the ELK JSON format.

elk.knownLayoutAlgorithms()

Returns a Promise with an array of registered layout algorithm descriptions.

elk.knownLayoutOptions()

Returns a Promise with an array of available layout options.

elk.knownLayoutCategories()

Returns a Promise with an array of layout categories.

elk.terminateWorker()

Terminates the Web Worker (if one was created).

Differences from elkjs

  • Written in Rust — compiled to WASM instead of GWT-transpiled JavaScript
  • No GWT overhead — faster startup, smaller memory footprint
  • Native Node.js addon — optional NAPI binding for maximum performance
  • Same API — elkjs-compatible layout(), knownLayoutAlgorithms(), etc.
  • Same algorithms — layered, stress, mrtree, radial, force, disco, rectpacking, sporeOverlap, sporeCompaction

Supported Algorithms

| Algorithm | ELK ID | |-----------|--------| | Layered | org.eclipse.elk.layered | | Stress | org.eclipse.elk.stress | | MrTree | org.eclipse.elk.mrtree | | Radial | org.eclipse.elk.radial | | Force | org.eclipse.elk.force | | DisCo | org.eclipse.elk.disco | | Rect Packing | org.eclipse.elk.rectpacking | | Spore Overlap | org.eclipse.elk.sporeOverlap | | Spore Compaction | org.eclipse.elk.sporeCompaction |

License

Eclipse Public License 2.0