Tooling for authoring perfscale libraries — WASM components that provide
value-generating functions to ${alias.fn(...)} tokens in
perfscale test payloads (RFC 005):
libraries:
- use: ./hello.wasm
capabilities: [] # explicit no-grants declaration; required by perfscale ≥ the upcoming release (pure component needs no grants)
steps:
- use: std/file-write@v1
with:
path: out.txt
content: "greeting: ${hello.greet(world)}" # → "greeting: hello, world!"The engine runs each library in a wasmtime sandbox under a fail-closed
capability model; the ABI contract (perfscale:library@0.2.0) is
ts/wit/library.wit, mirrored from the main repo's
single source of truth.
| Language | Status | Where |
|---|---|---|
| TypeScript / JavaScript | SDK + build tooling | ts/ (@perfscale/library-sdk) |
| Go | Example component (TinyGo + wit-bindgen-go, no SDK yet) | go/examples/hello |
| Rust | Full SDK, lives in the main repo | crates/perfscale-library-sdk |
$ cd ts && npm installWrite a library (mylib.ts):
import { args, defineLibrary } from "@perfscale/library-sdk";
export default defineLibrary({
name: "mylib",
functions: {
token: {
description: "Deterministic per-instance token; memo key reuses it within one message",
call(argv, ctx) {
const mint = () => `tok-${ctx.rng().nextU64().toString(16)}`;
const key = args.optionalString(argv, 0);
return key === undefined ? mint() : ctx.memo(key, mint);
},
},
},
});Build it to a WASM component with jco (ComponentizeJS embeds a JS engine — that is how TS becomes a component):
$ npx perfscale-library-build mylib.ts -o mylib.wasmReference it from your perfscale YAML (relative to the declaring file) and
call it from ${...} tokens in payloads.
The SDK also gives you:
-
Ctx— per-call context (messageSeq,iterationSeq,vuId,seed,timeMsasbigint),ctx.settings— the run's frozen settings snapshot (WIT 0.2settings-json),ctx.memo(key, fn)(keyed reuse within one message), andctx.rng()— a seeded xorshift64 PRNG bit-identical to the Rust SDK and the engine's built-in generator, soseed:runs reproduce. -
Args helpers (
args.string/int/float/optionalString) with author-friendly errors. -
testCall— a runtime-free harness fornode:testunit tests; no WASM needed:import assert from "node:assert/strict"; import { Ctx, testCall } from "@perfscale/library-sdk"; import lib from "./mylib.ts"; const ctx = new Ctx(42); assert.equal(testCall(lib, ctx, "token", []), testCall(lib, ctx, "token", []));
- jco (StarlingMonkey) components always import
wasi:filesystem/*andwasi:clocks/wall-clock, but that is toolchain noise: the SDK reports"pure": trueininfo()(it exposes no fs/clock APIs to authors), so engines honoring the pure marker waive the capability requirement and provide no preopens — declarecapabilities: [](explicit no-grants key, required by perfscale ≥ the upcoming release) and nothing more. On engines older than the pure-marker release the grant is still required (capabilities: [fs]on thelibraries:entry, onefsgrant satisfies both imports, plusallow_library_capabilities: truein the config) — old engines fail closed. The build already disableswasi:random,wasi:httpand timers, which the engine never grants — draw all randomness fromctx.rng()and all time fromctx.timeMs. - The WIT contract is vendored at
ts/wit/library.wit;ts/scripts/sync-wit.shre-fetches it pinned to a perfscale release tag (bumpPERFSCALE_TAGdeliberately).
Authoring (TS/JS) — a hermetic toolchain image, no host Node required:
$ docker build -t perfscale-library-build ts/docker
$ docker run --rm -v "$PWD:/src" -w /src perfscale-library-build mylib.ts -o mylib.wasmThe image is Node 24 + the published @perfscale/library-sdk (jco included);
pin the SDK with --build-arg SDK_VERSION=0.2.0 (ts/docker/Dockerfile).
Rust — the SDK lives in the engine repo; any rust:1.x image with
wasm32-wasip2 added (rustup target add wasm32-wasip2) builds components
with plain cargo. Go — the tinygo/tinygo image matches the recipe in
go/README.md.
Running libraries in Docker (engine images, mount layout, the install cache, and burned standalone binaries) is covered in the engine's Docker guide.
ts/ @perfscale/library-sdk — defineLibrary, Ctx, Prng, testCall,
perfscale-library-build (jco componentize glue), example
go/ Go guidance (README) + examples/hello — a working TinyGo
example component with committed wit-bindgen-go bindings
Dual-licensed under MIT or Apache-2.0, same as the main perfscale repo.