{"_id":"@bitruvius/turbo-jxl","_rev":"20-f02d7ccabb036f220a4550a6c9674960","name":"@bitruvius/turbo-jxl","dist-tags":{"latest":"0.3.3"},"versions":{"0.3.0":{"name":"@bitruvius/turbo-jxl","version":"0.3.0","keywords":["bitruvius","geospatial","webgl2","jxl","jpeg-xl","image","wasm","decoder"],"license":"SEE LICENSE IN LICENSE","_id":"@bitruvius/turbo-jxl@0.3.0","maintainers":[{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},{"name":"danrhedges","email":"danrhedges@gmail.com"}],"homepage":"https://dev.bitruvius.com/sdks/js/","bugs":{"url":"https://github.com/bitruvius/support"},"dist":{"shasum":"b97bfdbf5d286e9782dd8105363c863298ce05ef","tarball":"https://registry.npmjs.org/@bitruvius/turbo-jxl/-/turbo-jxl-0.3.0.tgz","fileCount":20,"integrity":"sha512-czBbP6cFDkaXzYULX/+MlRzuYqmWCqa8eDOEzS2VFZveNbMt/HpksWY51r622bsQYerqzZ8g7duNeCdhBFr8uQ==","signatures":[{"sig":"MEUCIF3ouRRVHVeeSyxoXjB8XgAyNBH1kwAWO5KrDVHqsXAfAiEAm2gMWPZjQcmUC5ckhLFjrC2lhGmWezXPr76uWkGel6I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2452471},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"b97bfdbf5d286e9782dd8105363c863298ce05ef","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./wasm/*":"./wasm/*","./package.json":"./package.json"},"scripts":{"test":"bun test","build":"bun build ./src/index.ts --outdir dist --format esm --target browser --minify --external '@bitruvius/*' --define __dirname='\"\"' --define __filename='\"\"' && tsc --emitDeclarationOnly"},"_npmUser":{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},"_integrity":"sha512-czBbP6cFDkaXzYULX/+MlRzuYqmWCqa8eDOEzS2VFZveNbMt/HpksWY51r622bsQYerqzZ8g7duNeCdhBFr8uQ==","_npmVersion":"10.8.3","description":"TurboJXL: JPEG XL image decoder for the browser, pure-Rust wasm","directories":{},"sideEffects":["./src/index.ts"],"_nodeVersion":"24.3.0","dependencies":{"@bitruvius/foundation":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/turbo-jxl_0.3.0_1785722146119_0.7450680609112583","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@bitruvius/turbo-jxl","version":"0.3.1","keywords":["bitruvius","geospatial","webgl2","jxl","jpeg-xl","image","wasm","decoder"],"license":"SEE LICENSE IN LICENSE","_id":"@bitruvius/turbo-jxl@0.3.1","maintainers":[{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},{"name":"danrhedges","email":"danrhedges@gmail.com"}],"homepage":"https://dev.bitruvius.com/sdks/js/","bugs":{"url":"https://github.com/bitruvius/support"},"dist":{"shasum":"c93506fc4a0131cc977ed4e87e46fd747f379c3b","tarball":"https://registry.npmjs.org/@bitruvius/turbo-jxl/-/turbo-jxl-0.3.1.tgz","fileCount":20,"integrity":"sha512-bmaQVa6e7gboedjpV377AGUpeorM7YWzrIM/uN4WKNkZLP4HosFrHNPY2Z5fkswPaOwq9MbeO4Sh3SoUF+PUqw==","signatures":[{"sig":"MEUCICWn7eVC8uwTiDB8noEbBqBNMH0NF7xnUIHi837Ffqp1AiEAnFdIy3O3glpGNHt60rSnm3Xrl9DEI9o7O8Fn6KK7sss=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2452636},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"c93506fc4a0131cc977ed4e87e46fd747f379c3b","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./wasm/*":"./wasm/*","./package.json":"./package.json"},"scripts":{"test":"bun test","build":"bun build ./src/index.ts --outdir dist --format esm --target browser --minify --external '@bitruvius/*' --define __dirname='\"\"' --define __filename='\"\"' && tsc --emitDeclarationOnly"},"_npmUser":{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},"_integrity":"sha512-bmaQVa6e7gboedjpV377AGUpeorM7YWzrIM/uN4WKNkZLP4HosFrHNPY2Z5fkswPaOwq9MbeO4Sh3SoUF+PUqw==","_npmVersion":"10.8.3","description":"TurboJXL: JPEG XL image decoder for the browser, pure-Rust wasm","directories":{},"sideEffects":["./src/index.ts"],"_nodeVersion":"24.3.0","dependencies":{"@bitruvius/foundation":"^0.3.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/turbo-jxl_0.3.1_1785725517048_0.29211090351487945","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@bitruvius/turbo-jxl","version":"0.3.2","keywords":["bitruvius","geospatial","webgl2","jxl","jpeg-xl","image","wasm","decoder"],"license":"SEE LICENSE IN LICENSE","_id":"@bitruvius/turbo-jxl@0.3.2","maintainers":[{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},{"name":"danrhedges","email":"danrhedges@gmail.com"}],"homepage":"https://dev.bitruvius.com/sdks/js/","bugs":{"url":"https://github.com/bitruvius/support"},"dist":{"shasum":"65dc8b60e4d5977b11db97ced3c3390e9aaf7afa","tarball":"https://registry.npmjs.org/@bitruvius/turbo-jxl/-/turbo-jxl-0.3.2.tgz","fileCount":20,"integrity":"sha512-/nEYgv3Hou7RIbWvHMG+zqo4no++jIKmqDY/jEkn7Nti3fj/uKJiss/xpJigjp/yGEwu9GZH/80SB2NPaJjCGQ==","signatures":[{"sig":"MEMCIERazpEarlm2dWoiqnWW0C8Nt9B+nMrVA60jJILmoSKFAh8UZ2ZNvnUYNOKgnVJtf9oaBE3SCCLMjEyEj+BYnG3M","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2452636},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"65dc8b60e4d5977b11db97ced3c3390e9aaf7afa","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./wasm/*":"./wasm/*","./package.json":"./package.json"},"scripts":{"test":"bun test","build":"bun build ./src/index.ts --outdir dist --format esm --target browser --minify --external '@bitruvius/*' --define __dirname='\"\"' --define __filename='\"\"' && tsc --emitDeclarationOnly"},"_npmUser":{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},"_integrity":"sha512-/nEYgv3Hou7RIbWvHMG+zqo4no++jIKmqDY/jEkn7Nti3fj/uKJiss/xpJigjp/yGEwu9GZH/80SB2NPaJjCGQ==","_npmVersion":"10.8.3","description":"TurboJXL: JPEG XL image decoder for the browser, pure-Rust wasm","directories":{},"sideEffects":["./src/index.ts"],"_nodeVersion":"24.3.0","dependencies":{"@bitruvius/foundation":"^0.3.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/turbo-jxl_0.3.2_1785952485479_0.2012426630953128","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"_id":"@bitruvius/turbo-jxl@0.3.3","bugs":{"url":"https://github.com/bitruvius/support"},"dist":{"shasum":"53c8c0222ef81d116a4c074bd5ce4f9ea702643d","tarball":"https://registry.npmjs.org/@bitruvius/turbo-jxl/-/turbo-jxl-0.3.3.tgz","fileCount":20,"integrity":"sha512-+/Rj6p8pMHUegcB0P0UC5DNa+slj+F1ctyqfF1YFJSzmXrncjjw6yxwuX0tOgQgPdOZxI5MHmeE2/6ah1Vlypw==","signatures":[{"sig":"MEYCIQCkNJ6UNjrMJccbt+Qp+KkhoDv208m8SeFldsD0RkLQoAIhALSOUFcsfUH7k8+3bfRMr3FuJcpAAifdpzF3Wndm6xoe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHLUBMRqaMHpJMlBFaGFSKpWgMdxLPslcdD/uXYnNvN+AiEAgCXWHFJzxqyydEP1a2oeXi4Xr/0IfXlTY9lDte2w3zc="}],"unpackedSize":2575056},"main":"./dist/index.js","name":"@bitruvius/turbo-jxl","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"53c8c0222ef81d116a4c074bd5ce4f9ea702643d","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./wasm/*":"./wasm/*","./package.json":"./package.json"},"license":"SEE LICENSE IN LICENSE","scripts":{"test":"bun test","build":"bun build ./src/index.ts --outdir dist --format esm --target browser --minify --external '@bitruvius/*' --define __dirname='\"\"' --define __filename='\"\"' && tsc --emitDeclarationOnly"},"version":"0.3.3","_npmUser":{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},"homepage":"https://dev.bitruvius.com/sdks/js/","keywords":["bitruvius","geospatial","webgl2","jxl","jpeg-xl","image","wasm","decoder"],"_integrity":"sha512-+/Rj6p8pMHUegcB0P0UC5DNa+slj+F1ctyqfF1YFJSzmXrncjjw6yxwuX0tOgQgPdOZxI5MHmeE2/6ah1Vlypw==","_npmVersion":"10.8.3","description":"TurboJXL: JPEG XL image decoder for the browser, pure-Rust wasm","directories":{},"maintainers":[{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},{"name":"danrhedges","email":"danrhedges@gmail.com"}],"sideEffects":["./src/index.ts"],"_nodeVersion":"24.3.0","dependencies":{"@bitruvius/foundation":"^0.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/turbo-jxl_0.3.3_1790299979160_0.5247230394973299"}}},"time":{"created":"2026-08-03T01:55:45.937Z","modified":"2026-09-25T01:32:59.464Z","0.2.0-alpha.0":"2026-06-12T04:19:57.030Z","0.2.0-alpha.1":"2026-06-12T13:08:22.565Z","0.2.0-alpha.2":"2026-06-12T14:55:02.075Z","0.2.0-alpha.3":"2026-06-17T04:39:35.333Z","0.2.0-alpha.4":"2026-06-18T01:20:35.186Z","0.3.0":"2026-08-03T01:55:46.315Z","0.3.1":"2026-08-03T02:51:57.223Z","0.3.2":"2026-08-05T17:54:45.646Z","0.3.3":"2026-09-25T01:32:59.269Z"},"bugs":{"url":"https://github.com/bitruvius/support"},"license":"SEE LICENSE IN LICENSE","homepage":"https://dev.bitruvius.com/sdks/js/","keywords":["bitruvius","geospatial","webgl2","jxl","jpeg-xl","image","wasm","decoder"],"description":"TurboJXL: JPEG XL image decoder for the browser, pure-Rust wasm","maintainers":[{"name":"geoffhtaylor3d","email":"geoffhtaylor3d@gmail.com"},{"name":"danrhedges","email":"danrhedges@gmail.com"}],"readme":"<p align=\"center\">\n  <a href=\"https://bitruvius.com\"><img src=\"https://cdn.bitruvius.com/brand/bitruvius-logo.png\" width=\"360\" alt=\"Bitruvius\"></a>\n</p>\n\n# @bitruvius/turbo-jxl\n\n**JPEG XL tiles decoded in the browser. No plugin, no fork.**\n\nTurboJXL is an encode-first, memory-safe JPEG XL codec built for\nnext-generation 256² and 512² tile pyramids: web maps, COG overviews, tile\nservers. This package is its decode side, a pure-Rust decoder compiled to\nsandboxed WebAssembly for browsers and Node/Bun (no emscripten, no C\ndependencies).\n\n> **Turbocharged by [Bitruvius TurboJXL](https://bitruvius.com/turbo-jxl).**\n\n## What makes it different\n\n**Memory-safe by construction.** The bitstream parser is pure Rust, which\neliminates the buffer-overflow, use-after-free and out-of-bounds CVE class you\ninherit when you parse untrusted image data in C. It then runs inside the\nWebAssembly sandbox on top of that.\n\n**Zero C dependencies.** No libjxl at runtime, no C compiler, no cmake. You\ninstall a package and decode.\n\n**Deterministic.** Bytes in, bytes out. Bitruvius reports the codec as\nbit-exact with libjxl 0.11.2 in both directions, with 285 / 285 samples passing\ncross-codec round-trip at e=1 / e=3 / e=7 on AVX2 and NEON. Those figures are\nmeasured on the native builds; this package ships the WebAssembly decoder.\n\n### The encoder side of the codec\n\nThese are the results Bitruvius publishes for the native TurboJXL encoder. The\nencoder is not part of this npm package (see [Install](#install)).\n\n| Encoder metric | Published result |\n|---|---|\n| Encode speed per core, versus `cjxl [e=7]` | ~42–71× faster, up to ~300× faster on large RGB tiles |\n| Throughput per core | 60–420 MP/s, against cjxl at 0.3–2.6 MP/s |\n| Output size versus `cjxl --effort=1` (libjxl's fast-lossless preset), at default TurboJXL settings | 2–28% smaller: 2–3% on RGB orthophoto and SAR quicklook tiles, 14–28% on AI inference masks |\n\nBitruvius states the caveat this way: \"Performance comparisons reflect our own\nmeasurements under the stated methodology; results vary by workload and\nhardware.\"\n\n## Use it\n\n```ts\nimport { JxlDecoder } from '@bitruvius/turbo-jxl';\n\nconst bytes = new Uint8Array(await (await fetch('/tile.jxl')).arrayBuffer());\nconst img = await new JxlDecoder().decode(bytes);\n// { width, height, hasAlpha, premultipliedAlpha, rgba: Uint8Array }\n```\n\n`rgba` is RGBA8, row-major from the top-left, so it goes straight to a canvas:\n\n```ts\nconst pixels = new Uint8ClampedArray(img.rgba.buffer, img.rgba.byteOffset, img.rgba.length);\nctx.putImageData(new ImageData(pixels, img.width, img.height), 0, 0);\n```\n\nOne decoder instance handles any number of images. The wasm loads lazily on\nyour first `decode()` and is shared across decoders in the same mode.\n\n## What decodes\n\nMeasured against the ISO/IEC 18181-3 conformance corpus: VarDCT and modular,\ngreyscale, 8- to 32-bit samples, straight and premultiplied alpha, patches,\nsplines, noise, progressive, upsampling, JPEG-recompressed streams, and the\nfirst frame of an animation.\n\nCoverage is broad but not complete. Streams built from multi-layer or\nblend-mode frame compositing, and streams carrying non-colour extra channels\n(CMYK `Black`, spot colour), reject. The package's conformance tests pin most\nof that matrix to real corpus bitstreams; the CMYK and spot-colour rejection\ncases are verified but not vendored, on file-size grounds.\n\n## Multithreaded decode (opt-in)\n\nA second build parallelizes decode across Web Workers. Enable it per decoder:\n\n```ts\nimport { JxlDecoder, canUseThreads } from '@bitruvius/turbo-jxl';\n\n// canUseThreads() reports whether this page is eligible, before you ask for it.\nconst img = await new JxlDecoder({ threads: canUseThreads() ? 'auto' : false }).decode(bytes);\n```\n\n`threads` takes `'auto'` (uses `navigator.hardwareConcurrency`, falling back to\n4), an explicit thread count, or `false`. It is honored only on a\ncross-origin-isolated page, so the host must send\n`Cross-Origin-Opener-Policy: same-origin` and\n`Cross-Origin-Embedder-Policy: require-corp`. Everywhere else, including Node\nand Bun, decode runs single-threaded rather than failing.\n\n`canUseThreads()` reports page eligibility, meaning `SharedArrayBuffer` plus\n`crossOriginIsolated`. It does not report which build actually loaded. An\neligible page can still fail to spawn the worker pool, most often when the SDK\nitself is served cross-origin from a CDN with no same-origin worker; decode logs\na warning and continues single-threaded.\n\n## Install\n\n```sh\nnpm i @bitruvius/turbo-jxl\n```\n\nThe only runtime dependency is `@bitruvius/foundation`. There are no peer\ndependencies and no native build step. Single-threaded decode is the default\nand runs everywhere: browsers, Node 18+ and Bun.\n\nThree wasm artifacts ship in the package and the right one is selected for you:\na universal `+simd128` build, a `+relaxed-simd` build used automatically on\nengines that validate the opcode (Chrome 114+, Firefox 120+, Safari 18+), and\nthe opt-in threaded build. All three resolve relative to the package. To serve\nthem from your own CDN, set the base URL once:\n\n```ts\nimport { configure } from '@bitruvius/foundation';\n\nconfigure({ wasmBaseUrl: 'https://cdn.example.com/bitruvius/wasm/' });\n```\n\nNode and Bun do not fetch the sibling asset, so hand the decoder the bytes:\n\n```ts\nimport { readFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { JxlDecoder } from '@bitruvius/turbo-jxl';\n\nconst resolve = createRequire(import.meta.url).resolve;\nconst wasmBytes = await readFile(resolve('@bitruvius/turbo-jxl/wasm/turbojxl_wasm_bg.wasm'));\nconst img = await new JxlDecoder({ wasmInit: { wasmBytes } }).decode(bytes);\n```\n\nA self-contained ESM bundle is published on the Bitruvius CDN if you would\nrather skip the bundler.\n\n**This package decodes. It does not encode.** The encode-side results above\ncome from the native TurboJXL codec, and the libjxl drop-in for `cjxl` and\n`djxl` is listed on bitruvius.com as coming soon. Install this expecting a\ndecoder.\n\nThe SDK license is royalty-free for commercial and non-commercial applications.\nSee LICENSE for the terms.\n\n## Learn more\n\n- **[Live examples](https://dev.bitruvius.com/bitruvius-sdk-js/examples/)**: running, with source\n- **[Documentation](https://dev.bitruvius.com/sdks/js/)**: guides and the full API reference\n- **[Support](https://github.com/bitruvius/support)**: questions and issues\n- **[TurboJXL on bitruvius.com](https://bitruvius.com/turbo-jxl)**: benchmarks and format details\n\n## Trademarks\n\nJPEG XL is a standard of the Joint Photographic Experts Group. libjxl is the\nreference JPEG XL implementation, and `cjxl` and `djxl` are its encoder and\ndecoder tools, published by the libjxl project under the BSD-3-Clause license.\nNode.js is a trademark of the OpenJS Foundation. All other marks are the\nproperty of their respective owners.\n\nThese names are used solely to describe the data formats this software\ninteroperates with. Bitruvius is not affiliated with, sponsored by, or endorsed\nby any of them, and no such relationship is implied.\n\n## License\n\nProprietary. The full terms ship as `LICENSE` inside this package, and are readable\nbefore installing at [cdn.bitruvius.com/legal/sdk-license-v1.txt](https://cdn.bitruvius.com/legal/sdk-license-v1.txt).\n\n© Bitruvius, Inc.\n","readmeFilename":"README.md"}