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

texture2ddecoder-wasm

v1.2.2

Published

WebAssembly bindings for Texture2DDecoder - decode various texture formats (BC1-7, ETC, PVRTC, ASTC, etc.) with Unity asset decoder

Downloads

547

Readme

texture2ddecoder-wasm

npm version License: MIT Node.js

A WebAssembly-based JavaScript/TypeScript library for decoding compressed texture formats. This project was inspired by K0lb3's texture2ddecoder Python wrapper and brings the same powerful texture decoding capabilities to Node.js and web environments through WebAssembly.

Built on top of Perfare's Texture2DDecoder from AssetStudio, with cross-platform WebAssembly bindings for JavaScript/TypeScript environments.

Features

  • Zero native dependencies - Pure WebAssembly, works on any platform
  • Browser and Node.js compatible - Works in both browser and Node.js environments
  • Comprehensive format support - Decode BC1-7, ETC1/2, PVRTC, ASTC, ATC, EAC, and Crunch formats
  • TypeScript support - Full type definitions included
  • Unity Asset support - Decode textures from Unity game assets
  • Fast performance - Native-speed decoding via WebAssembly

Supported Formats

BCn (Block Compression)

  • BC1 (DXT1) - RGB compression
  • BC3 (DXT5) - RGBA compression
  • BC4 - Single channel compression
  • BC5 - Dual channel compression
  • BC6 - HDR compression
  • BC7 - High quality compression

ETC (Ericsson Texture Compression)

  • ETC1 - RGB compression
  • ETC2 - Improved RGB compression
  • ETC2A1 - RGB + 1-bit alpha
  • ETC2A8 - RGB + 8-bit alpha

EAC (Ericsson Alpha Compression)

  • EAC R11 - Single channel
  • EAC R11 (signed) - Single channel signed
  • EAC RG11 - Dual channel
  • EAC RG11 (signed) - Dual channel signed

Other Formats

  • PVRTC - PowerVR Texture Compression (2bpp and 4bpp)
  • ASTC - Adaptive Scalable Texture Compression (various block sizes)
  • ATC - AMD Texture Compression (RGB4 and RGBA8)
  • Crunch - Crunch compressed textures
  • Unity Crunch - Unity's variant of Crunch compression

Installation

npm install texture2ddecoder-wasm

or

yarn add texture2ddecoder-wasm

🚀 New to this library? Check out the Quick Start Guide for the fastest way to get running!
📖 Need bundler setup? See the Complete Bundler Guide for detailed configurations.

Usage

💡 See the examples/ directory for complete working configurations for popular frameworks!

Node.js Usage

import { decode_astc } from "texture2ddecoder-wasm";
import * as fs from "fs";

// Load compressed texture data
const data = fs.readFileSync("texture.astc");

// Decode ASTC texture
const width = 512;
const height = 512;
const blockWidth = 4;
const blockHeight = 4;

const decoded = await decode_astc(data, width, height, blockWidth, blockHeight);

if (decoded) {
  // decoded is a Uint8Array containing BGRA pixel data
  // Use with image libraries like sharp, jimp, etc.
  console.log("Decoded successfully!");
}

Browser Usage with Modern Bundlers (Webpack, Vite, etc.)

For modern frameworks (React, Vue, Svelte, Next.js, etc.), you can use CDN for quick setup or local files for production:

Quick Start - Using CDN (Recommended for Development)

import { initialize, decode_bc1 } from "texture2ddecoder-wasm";

// Initialize with CDN
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// Load and decode texture
const response = await fetch("texture.bin");
const data = new Uint8Array(await response.arrayBuffer());
const decoded = await decode_bc1(data, 512, 512);

Benefits:

  • ✅ No manual file copying needed
  • ✅ Fastest setup time
  • ✅ Cached by CDN globally
  • ✅ Perfect for prototyping and development

Production Setup - Using Local Files

For production, copy WASM files to your public directory:

npx texture2ddecoder-copy-wasm public/wasm
import { initialize, decode_bc1 } from "texture2ddecoder-wasm";

// Initialize with local path
await initialize({ wasmPath: "/wasm" });

const decoded = await decode_bc1(data, 512, 512);

Benefits:

  • ✅ Faster loading (same domain)
  • ✅ Works offline
  • ✅ No external dependencies

Framework-Specific Examples:

Vite + React:

import { initialize, decode_bc1 } from "texture2ddecoder-wasm";

// Development: Use CDN
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// Production: Use local files (copy with: npx texture2ddecoder-copy-wasm public/wasm)
await initialize({ wasmPath: "/wasm" });

Next.js:

// In a 'use client' component
import { initialize, decode_bc1 } from "texture2ddecoder-wasm";

// Development: Use CDN
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// Production: Use local files (copy with: npx texture2ddecoder-copy-wasm public/wasm)
await initialize({ wasmPath: "/wasm" });

Webpack 5:

import { initialize, decode_bc1 } from "texture2ddecoder-wasm";

// Development: Use CDN
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// Production: Use local files (copy with: npx texture2ddecoder-copy-wasm public/wasm)
await initialize({ wasmPath: "/wasm" });

CDN Usage (jsDelivr)

You can use the library directly from jsDelivr CDN without any installation:

<!DOCTYPE html>
<html>
  <head>
    <title>Texture Decoder - CDN Example</title>
  </head>
  <body>
    <h1>Decode Textures from CDN</h1>
    <div id="status">Loading...</div>

    <script type="module">
      // Import from jsDelivr CDN
      import {
        initialize,
        decode_bc1,
      } from "https://cdn.jsdelivr.net/npm/[email protected]/dist/index.mjs";

      // Initialize with CDN path for WASM files
      await initialize({
        wasmPath:
          "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
      });

      document.getElementById("status").textContent = "✓ Ready to decode!";

      // Now you can use any decode function
      // const decoded = await decode_bc1(textureData, width, height);
    </script>
  </body>
</html>

Benefits:

  • ✅ Zero build setup
  • ✅ No npm install needed
  • ✅ Cached by jsDelivr globally
  • ✅ Perfect for quick prototypes

Production tip: Pin to a specific version (e.g., @1.2.1) instead of @latest for stability.

Complete working example: See examples/cdn-example.html for a full interactive demo.

Manual Initialization

import { initialize, decode_bc3 } from "texture2ddecoder-wasm";

// Node.js - no parameter needed (auto-detects module location)
await initialize();

// Browser - provide path to WASM files
await initialize({ wasmPath: "/wasm" });

// Browser with CDN - provide full CDN URL
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// Browser with custom locateFile for advanced use cases
await initialize({
  wasmPath: "/wasm",
  locateFile: (path) => `/custom-path/${path}`,
});

// Now decode functions will use the already-initialized module
const result = await decode_bc3(data, width, height);

API Reference

All decode functions accept Uint8Array | ArrayBuffer as input and return a Promise<Uint8Array | null>. The returned Uint8Array contains BGRA pixel data (4 bytes per pixel).

Note: In Node.js, you can still pass Buffer objects (which extend Uint8Array) and receive Uint8Array results that are compatible with Buffer operations.

BC Decoders

decode_bc1(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC1 (DXT1) compressed texture to BGRA.

decode_bc3(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC3 (DXT5) compressed texture to BGRA.

decode_bc4(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC4 compressed texture to BGRA.

decode_bc5(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC5 compressed texture to BGRA.

decode_bc6(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC6 compressed texture to BGRA.

decode_bc7(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes BC7 compressed texture to BGRA.

ETC Decoders

decode_etc1(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ETC1 compressed texture to BGRA.

decode_etc2(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ETC2 compressed texture to BGRA.

decode_etc2a1(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ETC2 with 1-bit alpha compressed texture to BGRA.

decode_etc2a8(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ETC2 with 8-bit alpha compressed texture to BGRA.

EAC Decoders

decode_eacr(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes EAC R11 compressed texture to BGRA.

decode_eacr_signed(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes EAC R11 signed compressed texture to BGRA.

decode_eacrg(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes EAC RG11 compressed texture to BGRA.

decode_eacrg_signed(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes EAC RG11 signed compressed texture to BGRA.

Other Format Decoders

decode_pvrtc(data: Uint8Array | ArrayBuffer, width: number, height: number, is2bpp: boolean = false): Promise<Uint8Array | null>

Decodes PVRTC compressed texture to BGRA.

  • is2bpp: Set to true for 2 bits-per-pixel mode, false for 4 bits-per-pixel (default)

decode_astc(data: Uint8Array | ArrayBuffer, width: number, height: number, blockWidth: number, blockHeight: number): Promise<Uint8Array | null>

Decodes ASTC compressed texture to BGRA.

  • blockWidth: Block width (typically 4, 5, 6, 8, 10, or 12)
  • blockHeight: Block height (typically 4, 5, 6, 8, 10, or 12)

decode_atc_rgb4(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ATC RGB4 compressed texture to BGRA.

decode_atc_rgba8(data: Uint8Array | ArrayBuffer, width: number, height: number): Promise<Uint8Array | null>

Decodes ATC RGBA8 compressed texture to BGRA.

Crunch Decoders

unpack_crunch(data: Uint8Array | ArrayBuffer): Promise<Uint8Array | null>

Unpacks Crunch compressed data.

unpack_unity_crunch(data: Uint8Array | ArrayBuffer): Promise<Uint8Array | null>

Unpacks Unity Crunch compressed data.

Initialization

initialize(options?: { wasmPath?: string; locateFile?: (path: string, prefix: string) => string }): Promise<void>

Manually initialize the WebAssembly module. This is called automatically on first use of any decode function in Node.js, but must be called explicitly in browser environments.

Parameters:

  • options.wasmPath - (Browser required) Path or URL to the directory containing WASM files
  • options.locateFile - (Optional) Custom function to locate WASM binary files for advanced use cases

Node.js Example:

await initialize(); // Auto-detects and loads from dist/wasm/

Browser Examples:

// Basic usage - local path
await initialize({ wasmPath: "/wasm" });

// With CDN
await initialize({
  wasmPath: "https://cdn.jsdelivr.net/npm/[email protected]/wasm",
});

// With custom locateFile for advanced scenarios
await initialize({
  wasmPath: "/wasm",
  locateFile: (path) => `https://cdn.example.com/custom/${path}`,
});

Framework Integration: This approach works seamlessly with:

  • ✅ React / Next.js
  • ✅ Vue / Nuxt
  • ✅ Svelte / SvelteKit
  • ✅ Webpack 5 / Vite / Rollup
  • ✅ Server-Side Rendering (SSR) - Call initialize() in client-side code only

Building from Source

Prerequisites

  • Node.js ≥14.0.0
  • Docker - Required for building the WebAssembly module (no local Emscripten installation needed)

Install Docker from: https://www.docker.com/get-started

Build Steps

# Clone the repository
git clone https://github.com/fatal10110/texture2ddecoder-wasm.git
cd texture2ddecoder-wasm

# Install dependencies
npm install

# Build WebAssembly module (uses Docker + Emscripten)
npm run build:wasm

# Build TypeScript
npm run build:ts

# Or build both at once
npm run build

# Run tests
npm test

Build Scripts

  • npm run build:wasm - Build the WebAssembly module using Docker and Emscripten
  • npm run build:ts - Compile TypeScript
  • npm run build - Build both WASM and TypeScript
  • npm test - Run tests

About the Docker Build

The WebAssembly build uses Docker with the official Emscripten SDK image, which means:

  • No need to install Emscripten locally
  • Consistent build environment across all platforms
  • Automatic compiler toolchain setup
  • Works on Windows, macOS, and Linux

The build script (scripts/build-wasm.sh) automatically:

  1. Checks if Docker is installed
  2. Pulls the latest Emscripten SDK image
  3. Compiles the C++ texture decoders to WebAssembly
  4. Generates optimized WASM and JavaScript glue code

License & Credits

This project is licensed under MIT.

Inspired by K0lb3's texture2ddecoder Python library.

The texture compression codecs were derived from the following sources:

| Codec | License | Source | | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | ATC | MIT | Perfare/AssetStudio - Texture2DDecoderNative/atc.cpp | | ASTC | MIT | Ishotihadus/mikunyan - ext/decoders/native/astc.c | | BCn | MIT | Perfare/AssetStudio - Texture2DDecoderNative/bcn.cpp | | ETC | MIT | Ishotihadus/mikunyan - ext/decoders/native/etc.c | | f16 | MIT | Maratyszcza/FP16 | | PVRTC | MIT | Ishotihadus/mikunyan - ext/decoders/native/pvrtc.c | | Crunch | PUBLIC DOMAIN | BinomialLLC/crunch | | Crunch (Unity) | ZLIB | Unity-Technologies/crunch |

Related Projects

Contributing

Contributions are welcome! Please read our Contributing Guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes.

Quick Start for Contributors

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/YOUR_USERNAME/texture2ddecoder-wasm.git
  3. Initialize submodules: git submodule update --init --recursive
  4. Install dependencies: npm install
  5. Build the project: npm run build
  6. Run tests: npm test
  7. Create a branch, make your changes, and submit a Pull Request

See CONTRIBUTING.md for detailed guidelines.

Platform Support

  • Node.js: ≥14.0.0
  • Browsers: Modern browsers with WebAssembly support (Chrome, Firefox, Safari, Edge)
  • Operating Systems: Windows, macOS, Linux (WebAssembly is platform-independent)

Browser Compatibility

The package works in all modern browsers that support:

  • WebAssembly
  • ES6 Modules (or use a bundler like Webpack/Vite)
  • Typed Arrays (Uint8Array)

Tested and working in:

  • Chrome/Edge 57+
  • Firefox 52+
  • Safari 11+
  • Opera 44+

Examples

See browser-example.html for a complete browser usage example.