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

jolt-ts

v0.1.1

Published

TypeScript-first ergonomic wrapper for Jolt Physics WASM

Readme

jolt-ts

TypeScript-first ergonomic bindings for Jolt Physics WASM.

📖 Documentation & live examples: https://snackdotgame.github.io/jolt-ts/

The package owns its raw WASM build instead of depending on the published jolt-physics npm package. The vendored binding layer lives in native/jolt and fetches Jolt C++ directly during pnpm run build:native.

pnpm add jolt-ts

WASM Builds

The wrapper supports every generated WASM variant:

  • wasm-compat
  • wasm
  • debug-wasm-compat
  • wasm-compat-multithread
  • wasm-multithread
  • debug-wasm-compat-multithread

wasm-compat is the default because the WASM binary is embedded in the JS bundle and works without asset plumbing:

const world = await World.create();

Bodies can be created with object literals or fluent descriptors:

const box = world.createBody({
  type: "dynamic",
  shape: Shape.box({ halfExtents: [0.5, 0.5, 0.5] }),
  position: [0, 4, 0],
  layer: "moving"
});

const ball = world.createBody(
  Body.dynamic()
    .shape(Shape.sphere(0.5))
    .translation(0, 8, 0)
    .layer("moving")
);

External WASM builds can use either upstream-style locateFile or the wrapper's wasmUrl shortcut:

const runtime = await loadJolt({
  build: "wasm",
  wasmUrl: "/assets/jolt-physics.wasm.wasm"
});

const world = await World.create({ runtime });

Multithreaded builds are selectable the same way, but the host page/runtime must support Jolt's thread requirements.

The npm package includes the generated Jolt JS/WASM artifacts for all supported build variants, including debug and multithreaded builds. Prefer loadJolt() for normal use; the ./native/jolt/dist/* export is available for advanced integrations that need direct access to the generated initializers.

Native Build

Build the raw Jolt artifacts before running tests or packing from a clean clone:

pnpm run build:native

The native build requires Emscripten, CMake, Python, and Node. It compiles Jolt with CROSS_PLATFORM_DETERMINISTIC=ON by default. Runtime deterministic stepping is still explicit:

const world = await World.create({ deterministic: "cross-platform" });

Initial network synchronization uses two binary payloads:

const scene = serverWorld.takeSceneSnapshot();
const state = serverWorld.saveState();

const clientWorld = await World.create({ deterministic: "cross-platform" });
clientWorld.restoreSceneSnapshot(scene);
clientWorld.restoreState(state);

The state APIs keep Jolt's native parameter order after the recorder argument:

using recorder = serverWorld.createStateRecorder();
serverWorld.saveState(recorder, "all", stateFilter);
clientWorld.restoreState(recorder, stateFilter);

For the common byte-oriented path, omit the recorder and saveState() returns a Uint8Array:

const state = serverWorld.saveState("all", stateFilter);
clientWorld.restoreState(state, stateFilter);

For game-loop code, prefer caller-owned buffers and reusable recorders:

const position = new Float32Array(3);
const rotation = new Float32Array(4);
const recorder = world.createStateRecorder();

body.translationInto(position);
body.rotationInto(rotation);
body.setLinearVelocity(1, 0, 0);
body.applyImpulse(0, 2, 0);

recorder.clear();
world.saveState(recorder);
sendState(recorder.view());

Use recorder.bytes() when you need an owned copy. recorder.view() avoids that copy, so treat the returned view as short-lived and invalidate it before clear(), rewind(), or dispose().

saveState() is the native Jolt SaveState payload for positions, velocities, active state, contacts, and other simulation-owned state. It only restores into bodies that already exist — restoreState() never creates or destroys bodies. For rollback, keep a ring buffer of saveState() bytes and replay inputs after restoreState(); keep both peers in lockstep by applying body add/remove events in the same order so Jolt assigns matching body IDs (or pin IDs with the raw CreateBodyWithID). Use a StateRecorderFilter to save only a subset of bodies.

takeSceneSnapshot() is the whole-world serialization — bodies, configuration, shapes, constraints, and preserved Jolt body IDs — via Jolt's PhysicsScene. It is for saving/loading a world or a one-shot full resync of a fresh peer, not for incrementally syncing topology changes.

See docs/api-directions.md for design notes.