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

tassetloader

v1.0.1

Published

[![NPM Version](https://img.shields.io/npm/v/tassetloader.svg)](https://www.npmjs.com/package/tassetloader) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0.html)

Downloads

13

Readme

TassetLoader 🚀

NPM Version License: LGPL v3

tassetloader is a high-performance developer library designed to load, parse, and instantiate optimized .tasset files in Three.js environments. It acts as the bridging runtime package for assets generated by your .tasset compiler and optimizer tool.

By packing meshes, texture hierarchies, Level of Detail (LOD) configurations, and pre-computed physics bounds directly into a unified .tasset container, this loader minimizes loading times, handles texture transcoding out of the box, and generates stable physics colliders with zero runtime computational overhead.


🌟 Key Advantages

  • ⚡ Ultra-Fast Load Times: Loads complex 3D assets, materials, and transcoded textures in a single request.
  • 📐 Automatic LOD Setup: Re-constructs Three.js LOD (Level of Detail) hierarchies automatically based on pre-compiled asset metadata.
  • 🛡️ Zero-Cost Physics Colliders: Extracts pre-generated Axis-Aligned Bounding Box (AABB) data and Convex Hull vertices directly from the file, avoiding expensive runtime collision geometry generation.
  • 🌳 Tree-Shakable & Modular: Features separate subpath exports for Three.js physics integrations to keep production bundles tiny:
    • tassetloader/cannon (for Cannon-ES)
    • tassetloader/rapier (for Rapier3D WASM)
    • tassetloader/jolt (for Jolt Physics WASM/NPM)

📦 Installation

Install the package via npm:

npm install tassetloader

Peer Dependencies

To keep the bundle lightweight, Three.js and the physics engines are marked as optional peer dependencies. Install only the libraries you plan to use in your project:

# Core dependency (Required)
npm install three

# Physics engines (Optional - install what you need)
npm install cannon-es             # For Cannon-ES physics
npm install @dimforge/rapier3d-compat # For Rapier3D WASM physics
npm install jolt-physics          # For Jolt Physics NPM package

🚀 Quick Start (Three.js Setup)

Configure the KTX2Loader (for texture transcoding) and load a .tasset model:

import * as THREE from 'three';
import { TassetLoader } from 'tassetloader';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';

// 1. Setup Three.js Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild(renderer.domElement);

// 2. Configure KTX2 texture transcoder path
const ktx2Loader = new KTX2Loader();
ktx2Loader.setTranscoderPath('/basis/'); // Path to transcoder scripts
ktx2Loader.detectSupport(renderer);

// 3. Register KTX2 Loader with TassetLoader
TassetLoader.setKTX2Loader(ktx2Loader);

// 4. Load the asset
const { group, metadata } = await TassetLoader.load('/models/chair.tasset');
scene.add(group);

console.log('Model loaded successfully!', group);
console.log('Pre-computed Physics Metadata:', metadata);

🛠️ Physics Engine Integrations (Subpaths)

Instead of importing physics helper functions from the main package, import them from their respective modular subpaths to keep your production bundles optimized.

1. Cannon-ES Integration (tassetloader/cannon)

Creates a physics CANNON.Body representing either an AABB box or a compound of pre-computed convex hulls, and syncs it with a wrapping Three.js group.

import * as THREE from 'three';
import * as CANNON from 'cannon-es';
import { TassetLoader } from 'tassetloader';
import { createAABBBody, createHullBody } from 'tassetloader/cannon';

const world = new CANNON.World({ gravity: new CANNON.Vec3(0, -9.82, 0) });
const { group } = await TassetLoader.load('/chair.tasset');

// Create an Axis-Aligned Bounding Box (AABB) physics body
const aabbSim = createAABBBody(
  world, 
  group, // Model containing pre-computed AABB metadata
  new THREE.Vector3(-2, 5, 0), // Position
  group.clone(), // Visual mesh wrapper
  { mass: 1, linearDamping: 0.4 }
);
scene.add(aabbSim.wrapper);

// Sync visual models with physics positions in your animation loop
function tick() {
  world.fixedStep();
  aabbSim.wrapper.position.copy(aabbSim.body.interpolatedPosition as any);
  aabbSim.wrapper.quaternion.copy(aabbSim.body.interpolatedQuaternion as any);
}

2. Rapier3D Integration (tassetloader/rapier)

Creates a RAPIER.RigidBody and sets up the corresponding colliders (cuboids or convex hulls) inside the Rapier simulation.

import * as THREE from 'three';
import RAPIER from '@dimforge/rapier3d-compat';
import { TassetLoader } from 'tassetloader';
import { createAABBRapierBody } from 'tassetloader/rapier';

await RAPIER.init();
const world = new RAPIER.World({ x: 0.0, y: -9.82, z: 0.0 });
const { group } = await TassetLoader.load('/chair.tasset');

const aabbSim = createAABBRapierBody(
  world,
  group,
  new THREE.Vector3(-2, 5, 0),
  group.clone(),
  { mass: 1, allowSleep: true }
);
scene.add(aabbSim.wrapper);

// Sync in animation loop
function tick() {
  world.step();
  const pos = aabbSim.body.translation();
  const rot = aabbSim.body.rotation();
  aabbSim.wrapper.position.set(pos.x, pos.y, pos.z);
  aabbSim.wrapper.quaternion.set(rot.x, rot.y, rot.z, rot.w);
}

3. Jolt Physics Integration (tassetloader/jolt)

Integrates seamlessly with either your custom multithreaded WASM builds or the official jolt-physics package.

import * as THREE from 'three';
import { TassetLoader } from 'tassetloader';
import { createAABBJoltBody } from 'tassetloader/jolt';
import initJolt from 'jolt-physics';

const jolt = await initJolt();

// 1. Configure Jolt collision layers
const LAYER_NON_MOVING = 0;
const LAYER_MOVING = 1;
const NUM_LAYERS = 2;

// Enable collision between non-moving vs moving, and moving vs moving objects
const objVsObjFilter = new jolt.ObjectLayerPairFilterTable(NUM_LAYERS);
objVsObjFilter.EnableCollision(LAYER_NON_MOVING, LAYER_MOVING);
objVsObjFilter.EnableCollision(LAYER_MOVING, LAYER_MOVING);

const BP_LAYER_NON_MOVING = new jolt.BroadPhaseLayer(0);
const BP_LAYER_MOVING = new jolt.BroadPhaseLayer(1);
const NUM_BP_LAYERS = 2;

const bpLayerInterface = new jolt.BroadPhaseLayerInterfaceTable(NUM_LAYERS, NUM_BP_LAYERS);
bpLayerInterface.MapObjectToBroadPhaseLayer(LAYER_NON_MOVING, BP_LAYER_NON_MOVING);
bpLayerInterface.MapObjectToBroadPhaseLayer(LAYER_MOVING, BP_LAYER_MOVING);

const objVsBpFilter = new jolt.ObjectVsBroadPhaseLayerFilterTable(
  bpLayerInterface,
  NUM_BP_LAYERS,
  objVsObjFilter,
  NUM_LAYERS
);

// 2. Initialize the Jolt Settings & Interface
const settings = new jolt.JoltSettings();
settings.mObjectLayerPairFilter = objVsObjFilter;
settings.mObjectVsBroadPhaseLayerFilter = objVsBpFilter;
settings.mBroadPhaseLayerInterface = bpLayerInterface;

const joltInterface = new jolt.JoltInterface(settings);
const bodyInterface = joltInterface.GetPhysicsSystem().GetBodyInterface();

// Clean up temporary setup settings
jolt.destroy(settings);

// 3. Load the model and create a Jolt physics body
const { group } = await TassetLoader.load('/chair.tasset');

const aabbSim = createAABBJoltBody(
  jolt,
  bodyInterface,
  group,
  new THREE.Vector3(-2, 5, 0),
  group.clone(),
  { mass: 1 }
);
scene.add(aabbSim.wrapper);

🎮 Running the Demo Locally

This repository includes a demo project in the demo/tassetdemo directory showcasing integrations with Cannon-ES, Rapier3D, and Jolt Physics.

To run the demo locally:

  1. Build the main library at the project root:

    npm run build
  2. Navigate to the demo folder:

    cd demo/tassetdemo
  3. Install the dependencies:

    npm install
  4. Start the development server:

    npm run dev

Open http://localhost:5173 (or the URL displayed in your terminal) in your browser to see the loader and physics simulations in action.


📄 License

This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0-only). See the LICENSE file for the full terms.