The engine in the browser
The same engine as WebAssembly: a JSON document tree in, PDF bytes out, in a browser.
npm install @inkoxide/wasm
import { init, registerFont, renderSync, InkoxideError } from '@inkoxide/wasm';
// Once: compiles `inkoxide.wasm`, which bundlers resolve next to this module.
await init();
registerFont('Inter-Regular', new Uint8Array(await (await fetch('/fonts/Inter-Regular.ttf')).arrayBuffer()));
const doc = {
version: 1,
fonts: [{ id: 'Inter-Regular', family: 'Inter' }],
pages: [{ size: { width: 595.28, height: 841.89 },
children: [{ type: 'text', runs: [{ text: 'Hello', font: 'Inter-Regular', size: 24 }] }] }],
};
try {
const pdf = renderSync(JSON.stringify(doc));
const url = URL.createObjectURL(new Blob([pdf], { type: 'application/pdf' }));
} catch (e) {
if (!(e instanceof InkoxideError)) throw e;
console.error(e.code, e.path, e.message);
}
How it differs from inkoxide:
- One thread. Renders run on the calling thread,
renderincluded: in a page, render in a Web Worker.threadsmay only be1. - JSON only.
format: 'msgpack'is aPARSE_ERROR. - Downloads on demand. The module (about 1.2 MB with brotli) leaves out the built-in
hyphenation patterns:
renderfetches a language's fromhyphenation/next to the module the first time a document hyphenates text in it, and the fonts of itsdeferredFontsoption (id → URL) that a document draws with, or needs as a fallback.renderSynccannot fetch, and fails withNOT_LOADED: callloadHyphenation(['de'])first, or userender. init(source?)takes a URL, aResponse, the bytes or a compiledWebAssembly.Module. It needs no cross-origin isolation; a Content Security Policy needsscript-src 'wasm-unsafe-eval'.- A bug in the engine (
INTERNAL) ends its instance: the next call runs in a new one, with the fonts and hyphenation patterns registered so far, which the package keeps a copy of. - Memory grows and is not given back.
clearCaches()empties the caches renders share, for later renders to reuse the memory. - Fonts. A WOFF2 font gives other PDF bytes than its TrueType file.
From a CDN, give init the module with its
Subresource Integrity
hash, so that the browser refuses any other bytes, and the folder of the
hyphenation patterns:
const base = 'https://cdn.jsdelivr.net/npm/@inkoxide/wasm@<version>/';
await init(fetch(`${base}inkoxide.wasm`, { integrity: 'sha384-<hash of inkoxide.wasm>' }), {
hyphenation: `${base}hyphenation/`,
});
The README published with each version on npm has its version and hash here.
Options, defaults and error codes are typed in index.d.ts and described in
the API reference.
Synced from packages/wasm/README.md in the inkoxide repository.