This repository has been moved.
The babylonpress-ktx2-encoder package is now maintained as part of the glb-optimizer-v2 monorepo.
📦 Package: glb-optimizer-v2/packages/babylonpress-ktx2-encoder
- All future development, bug fixes, and releases will happen in the new location
- The standalone repository is now read-only and will not receive further updates
- The package name on npm (
babylonpress-ktx2-encoder) remains unchanged - Existing installations continue to work, but we recommend updating your imports or references to point to the new location if you're contributing
The package has been consolidated into the glb-optimizer-v2 monorepo to improve maintainability, enable better integration with related tools, and streamline the development workflow.
Visit the new package location for:
- Latest source code
- Updated documentation
- Issue tracking
- Contribution guidelines
This repository was archived on July 06, 2026.
KTX2 (.ktx2) encoding utilities for browser and Node.js applications, built on Basis Universal.
This package is maintained in the eldinor/ktx2-encoder fork and builds on the original work by Hu Song.
npm install babylonpress-ktx2-encoder- browser encoding
- browser worker encoding
- browser worker pool encoding for batch jobs
- Node.js encoding
- glTF-Transform integration
import { encodeToKTX2 } from "babylonpress-ktx2-encoder";
const png = new Uint8Array(await fetch("/texture.png").then((res) => res.arrayBuffer()));
const ktx2 = await encodeToKTX2(png, {
isUASTC: true,
generateMipmap: true
});By default, the browser build resolves its bundled Basis JS and WASM assets automatically.
Use worker: true when you want background encoding without changing the main API:
const ktx2 = await encodeToKTX2(png, {
isUASTC: true,
generateMipmap: true,
worker: true
});This is mainly about keeping the UI responsive. It usually does not make a single encode much faster.
Use a pool for batch conversion:
import { createKTX2WorkerPool, encodeToKTX2 } from "babylonpress-ktx2-encoder";
const pool = createKTX2WorkerPool({ size: 4 });
const ktx2 = await encodeToKTX2(png, {
isUASTC: true,
generateMipmap: true,
worker: pool
});
const results = await pool.encodeMany([
{
imageBuffer: textureA,
options: { isUASTC: true, generateMipmap: true }
},
{
imageBuffer: textureB,
options: { isUASTC: true, generateMipmap: true }
}
]);
pool.terminate();Pool size can be:
- omitted, which defaults to
2 - a number like
1,2,4 "auto", which uses a conservativehardwareConcurrencyheuristic
const pool = createKTX2WorkerPool({ size: "auto" });worker: trueuses a shared default worker client- worker encoding does not support a custom
imageDecoderfunction wasmUrlandjsUrlcan still be overridden when custom hosting is needed
Node requires an imageDecoder for LDR inputs.
import fs from "node:fs/promises";
import sharp from "sharp";
import { encodeToKTX2 } from "babylonpress-ktx2-encoder";
async function imageDecoder(buffer: Uint8Array) {
const image = sharp(buffer);
const metadata = await image.metadata();
const rawBuffer = await image.ensureAlpha().raw().toBuffer();
return {
width: metadata.width!,
height: metadata.height!,
data: new Uint8Array(rawBuffer)
};
}
const png = new Uint8Array(await fs.readFile("./texture.png"));
const ktx2 = await encodeToKTX2(png, {
isUASTC: true,
generateMipmap: true,
imageDecoder
});import { ktx2 } from "babylonpress-ktx2-encoder/gltf-transform";
await document.transform(
ktx2({
isUASTC: true,
generateMipmap: true
})
);A local benchmark page is included for comparing:
- main-thread encode
- single worker encode
- worker pool batch encode
Run it with:
npm run benchmarkThe page is served from /benchmark/.
See API.md for a focused API reference.
npm run build
npm test
npm run test:web
npm run test:gltf
npm run test:gltf:web
npm run test:coverage
npm run dev