Skip to content

Repository files navigation

mupdf-wasm

New here? See QUICKSTART.md.

MuPDF built as a WASI 0.2 component, using wasi-sdk 33 targeting wasm32-wasip2. Loads under wasmtime and under any host that speaks the component model — including wasmos in the browser lane.

Layout

wit/mupdf.wit            # artifex:mupdf@0.1.0 — types + document + convenience
src/component.c          # C glue between wit-bindgen output and MuPDF C API
third_party/mupdf/       # git submodule, pinned to 1.28.2
scripts/
  install-wasi-sdk.sh    # wasi-sdk 33 for the host OS/arch → toolchain/wasi-sdk
  install-tools.sh       # wit-bindgen + wasm-tools → toolchain/bin
Makefile

Quickstart

# 1. Populate submodules
git submodule update --init --recursive

# 2. Fetch toolchain (wasi-sdk 33 + wit-bindgen + wasm-tools)
make tools

# 3. Build build/mupdf.component.wasm
make

The last step wraps the wasip2 core module as a WASI 0.2 component and echoes the resolved WIT so you can see the export shape at a glance.

Overrides

Var Default What it does
WASI_SDK_DIR ./toolchain/wasi-sdk Point at an existing wasi-sdk install
WIT_BINDGEN $(command -v wit-bindgen) Use a system wit-bindgen
WASM_TOOLS $(command -v wasm-tools) Use a system wasm-tools

Example:

make WASI_SDK_DIR=/opt/wasi-sdk-33.0

API surface

world mupdf exports two interfaces (both in wit/mupdf.wit):

  • document — a resource: open once, then call metadata, page-count, page-info, outline, render-page, extract-text, search, page-to-svg, page-to-html, to-clean-pdf.
  • convenience — one-shot bytes-in/bytes-out helpers: render-first-page, document-info, extract-all-text.

Errors are a variant covering io, invalid-document, password-required, wrong-password, not-supported, out-of-range, internal.

Running against wasmtime

wasmtime run --wasi=preview2 -S component-model=y build/mupdf.component.wasm

Since the component doesn't export a wasi:cli/run entrypoint, host code (Rust with wasmtime::component::bindgen!, or JS via jco transpile) must instantiate it and call the exported functions directly.

Running under wasmos (browser)

Transpile with jco inside your wasmos scaffold and consume it the same way your other guest-* examples do; the produced component uses only wasi:cli-agnostic imports so it works in both wasmtime and JS-host lanes.

Notes on the build

  • OS=wasip2 is passed to MuPDF's Makerules — no branch matches, so Makerules falls through to its Unix defaults, and every host-specific feature (X11, GLUT, libcrypto, pthreads, objcopy) is disabled through the HAVE_*=no overrides.
  • make generate runs on the host (portable shell + host CC) to build MuPDF's font/hyphenation/ICC data C files; only make libs is cross- compiled with wasi-sdk.
  • _WASI_EMULATED_MMAN and _WASI_EMULATED_SIGNAL are enabled so MuPDF's incidental use of mmap/signal links cleanly under wasip2.
  • The linker uses --gc-sections --no-entry; the component's entry points are the WIT exports, not a main.

Editor squiggles

Your LSP will complain about mupdf/fitz.h and mupdf.h on src/component.c until you've run make bindings at least once — those headers live under third_party/mupdf/include/ (populated by the submodule) and build/bindings/ (generated). Point compile_commands.json at build/bindings and third_party/mupdf/include if you want clean intellisense.

Bumping MuPDF

cd third_party/mupdf && git fetch --tags && git checkout <newer-tag> && cd -
git submodule update --init --recursive
make clean && make

License

MuPDF is AGPL-3.0 (commercial licence available from Artifex). This wrapper code is under the same terms.

About

MuPDF as a WASI 0.2 component (wasm32-wasip2, wasi-sdk 33)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages