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

@bitruvius/ktx2

v0.3.1

Published

KTX2/Basis texture transcoder seam for @bitruvius/gltf: transcode-only Basis Universal wasm (KHR_texture_basisu), vendored and hardened

Readme

@bitruvius/ktx2

The Basis Universal transcoder behind one injectable interface, so no parser in the SDK has to know KTX2 exists.

Internal building block. This package exists so that @bitruvius/sdk-maplibre and the Bitruvius codecs can resolve their dependencies on npm. It has no standalone product story. Unless you are deliberately building against it, install the SDK instead.

It transcodes a KHR_texture_basisu KTX2 container (ETC1S or UASTC) into a GPU texture format the renderer can upload, satisfying the Ktx2Transcoder contract declared in @bitruvius/geo-core.

Why it is its own package

The contract lives in @bitruvius/geo-core. The wasm that satisfies it lives here. That split is the reason the package exists.

Two decode paths need it, and neither may depend on the other. @bitruvius/gltf meets KHR_texture_basisu on the 3D Tiles side. @bitruvius/i3s meets the same textures on the I3S side, where 1.8+ services exist that publish KTX2 and nothing else. If either parser imported Basis directly, the other would have to duplicate the binary or take a dependency on a parser it has no business knowing about. A separate package that depends only on @bitruvius/geo-core closes both: no cycle, one copy of the wasm, and both parsers stay codec-agnostic.

The payload is real. basis_transcoder.wasm is about 515 KiB. Content that carries no KHR_texture_basisu should never pay for it, so the transcoder is injected rather than imported, and the wasm is fetched lazily on the first texture that actually asks for one.

The licence boundary is real too. The wasm is Binomial's Basis Universal transcoder under Apache-2.0, vendored transcode-only: the compressor is absent, and a publish-time check re-verifies that no encoder entry point crept back in. Keeping it in one package keeps the redistribution boundary, the licence texts and the attribution in one place, separate from the Bitruvius licence.

What is in it

| Export | What it does | |---|---| | Ktx2BasisTranscoder | The seam implementation. transcode(bytes, target), with lazy wasm init on the first call. | | transcodeKtx2(module, bytes, target) | The pure path, for when you already hold an initialized Basis module. | | ensureBasis(init?) | Instantiates and initializes the wasm once, then returns the shared module. A failed init clears the cache so the next call retries. | | basisWasmUrl() | The best absolute URL for the wasm, for handing to a Web Worker, which cannot resolve a package-sibling asset itself. undefined when neither a configured base nor the packaged sibling resolves. |

Targets are named by a backend-neutral hint: rgba32 is the universal fallback that uploads everywhere, and bc7, bc3, bc1, etc2, astc4x4 and pvrtc are the matching GPU-compressed block formats, chosen per device by the renderer. The whole mip chain is transcoded, one bulk fill per level straight into a right-sized buffer, with no intermediate copies.

Wire it into the glTF decoder:

import { Ktx2BasisTranscoder } from '@bitruvius/ktx2';
import { GltfMeshDecoder } from '@bitruvius/gltf';

const decoder = new GltfMeshDecoder({ ktx2: new Ktx2BasisTranscoder() });

Locating the wasm

The transcoder resolves its binary in precedence order: explicit wasmBytes, then an explicit wasmUrl, then the SDK-configured CDN base, then the packaged sibling asset. Point it at an explicit URL when a bundler or a cross-origin worker cannot resolve the sibling for you.

import { configure } from '@bitruvius/geo-core';

configure({ wasmBaseUrl: 'https://cdn.example.com/bitruvius/wasm/' });

const ktx2 = new Ktx2BasisTranscoder({
  wasmInit: { wasmUrl: 'https://cdn.example.com/bitruvius/wasm/basis_transcoder.wasm' },
});

The module is a per-realm singleton, so the first call decides how it was located. The raw asset is also reachable at the ./wasm/* subpath export if you need to serve or preload it yourself.

Who should depend on it

Inside the SDK: @bitruvius/tiles3d-mesh, @bitruvius/i3s and @bitruvius/sdk-maplibre, all of which construct one and pass it to a decoder. @bitruvius/gltf deliberately does not: it declares the seam and never imports the codec.

Outside the SDK, depend on it only if you are driving GltfMeshDecoder or the I3S mesh decoder yourself and you need KHR_texture_basisu support. If you are putting 3D content on a map, install @bitruvius/sdk-maplibre, which wires this in for you.

Third-party attribution

The wasm is Binomial's Basis Universal transcoder (basis_transcoder.wasm), Apache-2.0, vendored transcode-only (no compressor). See wasm/NOTICES, which ships in the published package alongside the full Apache-2.0 text.

The Bitruvius LICENSE restricts redistribution and reverse engineering of the SDK. Those restrictions do not reach the vendored Basis transcoder: it is licensed to you directly by its copyright holder under Apache-2.0, and where the two appear to conflict as applied to that file, the upstream licence governs.

Trademarks

Khronos, KTX and glTF are trademarks of The Khronos Group Inc. Basis Universal is a product of Binomial LLC. Esri, ArcGIS and I3S are trademarks of Environmental Systems Research Institute, Inc. Cesium and 3D Tiles are trademarks of Cesium GS, Inc. MapLibre is a trademark of the MapLibre organization. All other marks are the property of their respective owners.

These names are used solely to describe the data formats this software interoperates with. Bitruvius is not affiliated with, sponsored by, or endorsed by any of them, and no such relationship is implied.

License

Proprietary. The full terms ship as LICENSE inside this package, and are readable before installing at cdn.bitruvius.com/legal/sdk-license-v1.txt.

© Bitruvius, Inc.