Skip to content

Backends: Native vs WASM

@scaryterry/pdfium supports two distinct backends for executing PDF operations. Understanding the difference is key to optimising your application.

FeatureWASM BackendNative Backend
EnvironmentUniversal (Browser + Node)Node.js Only
SetupZero configurationRequires platform package
PerformanceHigh (Near-Native)Maximum (Direct C++)
MemoryManual / Garbage CollectedSystem Allocator
DependenciesNone (Bundled)Platform-specific (.node file)
PortabilityRuns anywhereOS/Arch specific
Interactive Forms✅ Full Support❌ Not yet supported
Document Creation✅ Supported❌ Not supported
Progressive Loading✅ Supported❌ Not supported

This is the default backend. It uses a WebAssembly-compiled version of the PDFium C++ library.

  • Universal: Runs in Chrome, Firefox, Safari, Edge, and Node.js.
  • Zero Config: The .wasm file is bundled with the package. No need to install separate binaries.
  • Secure: Runs inside the WASM sandbox, isolating memory access.
  • Overhead: Marshalling data (especially large images) between JavaScript memory and WASM memory has a cost.
  • Startup Time: Compiling the WASM module can take a few milliseconds (or longer on low-end devices).
// Uses WASM automatically
using pdfium = await PDFium.init();

The Native backend uses Node-API (N-API) to bind directly to the system’s compiled PDFium library.

  • Maximum Speed: Eliminates the WASM bridge overhead. Rendering large bitmaps is significantly faster because memory can be shared or copied more efficiently.
  • No Compilation: No WASM compilation step at runtime.
  • Setup: You must install the specific package for your operating system (e.g., @scaryterry/pdfium-darwin-arm64).
  • Node.js Only: Cannot be used in browsers.

First, install the platform package:

Terminal window
pnpm add @scaryterry/pdfium-darwin-arm64 # macOS M1/M2/M3
# OR
pnpm add @scaryterry/pdfium-linux-x64-gnu # Linux Server

Then, request the native backend in your code:

using pdfium = await PDFium.init({ useNative: true });

The init({ useNative: true }) call is designed to fail gracefully. If the native package is not found or fails to load, it will automatically fall back to the WASM backend (unless you throw an error manually).

(Approximate — measured on a simple test document; your results will vary with document complexity and hardware.)

OperationWASMNativeImprovement
Document load2.5ms1.8ms~1.4x
Page render (1×)15ms12ms~1.25x
Text extraction0.8ms0.5ms~1.6x
Character operations0.3ms0.15ms~2x

The native backend’s advantage grows with data-heavy operations (large bitmap renders, bulk character access) because it avoids WASM memory marshalling. For heavy rendering workloads or high-throughput server applications, the native backend is recommended. For CLI tools or lighter workloads, WASM is often sufficient and easier to distribute.