Installation
Use this guide to get a correct setup on the first try.
What You Will Finish With
Section titled “What You Will Finish With”- Core API running in Node.js or browser.
- React viewer running with a valid worker and WASM source.
- A quick verification step you can run before building features.
1. Install the Package
Section titled “1. Install the Package”pnpm add @scaryterry/pdfiumReact users also need peers:
pnpm add react react-dom lucide-react2. Pick Your Runtime Setup
Section titled “2. Pick Your Runtime Setup”| Environment | Required setup |
|---|---|
| Node.js core API | No extra asset wiring needed for basic PDFium.init() |
| Browser core API | Provide wasmUrl or wasmBinary to PDFium.init(...) |
React viewer (PDFiumProvider) | Provide workerUrl and (wasmUrl or wasmBinary) |
| Worker mode with core API | Create worker entry module and pass workerUrl |
3. Node.js Setup
Section titled “3. Node.js Setup”import { PDFium } from '@scaryterry/pdfium';
using pdfium = await PDFium.init();4. Browser Setup (Core API)
Section titled “4. Browser Setup (Core API)”import { PDFium } from '@scaryterry/pdfium';
const wasmBinary = await fetch('/pdfium.wasm').then((r) => r.arrayBuffer());using pdfium = await PDFium.init({ wasmBinary });You can also pass wasmUrl directly:
using pdfium = await PDFium.init({ wasmUrl: '/pdfium.wasm' });5. Canonical Worker Module (React + Worker Mode)
Section titled “5. Canonical Worker Module (React + Worker Mode)”Create a worker entry in your app:
import '@scaryterry/pdfium/worker';Resolve its URL:
const workerUrl = new URL('./pdfium.worker.ts', import.meta.url).toString();6. React Provider Bootstrap
Section titled “6. React Provider Bootstrap”import wasmUrl from '@scaryterry/pdfium/pdfium.wasm?url';import { PDFiumProvider, PDFViewer } from '@scaryterry/pdfium/react';
const workerUrl = new URL('./pdfium.worker.ts', import.meta.url).toString();
function App() { return ( <PDFiumProvider wasmUrl={wasmUrl} workerUrl={workerUrl}> <PDFViewer /> </PDFiumProvider> );}7. Choose an Asset Wiring Strategy
Section titled “7. Choose an Asset Wiring Strategy”Strategy A: Bundler-managed asset URLs (recommended)
Section titled “Strategy A: Bundler-managed asset URLs (recommended)”Use your bundler to emit both worker and WASM URLs.
Vite example:
import { defineConfig } from 'vite';
export default defineConfig({ optimizeDeps: { exclude: ['@scaryterry/pdfium'] }, assetsInclude: ['**/*.wasm'],});import wasmUrl from '@scaryterry/pdfium/pdfium.wasm?url';const workerUrl = new URL('./pdfium.worker.ts', import.meta.url).toString();Strategy B: Serve WASM from public/
Section titled “Strategy B: Serve WASM from public/”Copy the WASM file into your public assets:
cp node_modules/@scaryterry/pdfium/dist/vendor/pdfium.wasm public/pdfium.wasmThen use:
const wasmUrl = '/pdfium.wasm';Keep the worker as a bundled module (src/pdfium.worker.ts) and pass the emitted workerUrl.
Do not copy only dist/worker.js; it imports sibling modules.
8. Next.js Notes
Section titled “8. Next.js Notes”Enable async WASM in webpack:
module.exports = { webpack: (config) => { config.experiments = { ...config.experiments, asyncWebAssembly: true }; return config; },};If you serve from public, copy:
cp node_modules/@scaryterry/pdfium/dist/vendor/pdfium.wasm public/pdfium.wasm9. Optional Native Backend (Node.js)
Section titled “9. Optional Native Backend (Node.js)”Install platform package(s):
pnpm add @scaryterry/pdfium-darwin-arm64pnpm add @scaryterry/pdfium-darwin-x64pnpm add @scaryterry/pdfium-linux-x64-gnupnpm add @scaryterry/pdfium-linux-arm64-gnupnpm add @scaryterry/pdfium-win32-x64-msvcThen request native:
import { PDFium } from '@scaryterry/pdfium';const pdfium = await PDFium.init({ useNative: true });10. Verify Installation
Section titled “10. Verify Installation”import { PDFium, VERSION } from '@scaryterry/pdfium';
console.log('version', VERSION);using pdfium = await PDFium.init();console.log('ok');If this script prints a version and ok, your base setup is valid.