@docmentis/udoc-viewer
Universal document viewer for the web.
Open-source, framework-agnostic viewer powered by a built-from-scratch WebAssembly engine for high-fidelity rendering across PDF, DOCX, PPTX, and images.
Live Demo · Guide · Changelog · Report Issue
Why udoc-viewer?
Most web document viewers only handle PDF, rely on server-side rendering, or require expensive commercial licenses. udoc-viewer is different:
- Truly universal — PDF, Word, PowerPoint, and images in a single viewer, with more formats coming
- High fidelity — powered by a custom Rust/WebAssembly rendering engine, not PDF.js
- Client-side only — everything runs in the browser, no server round-trips
- Framework agnostic — works with React, Vue, Angular, Svelte, or plain HTML
- Free for commercial use — MIT-licensed wrapper, free WASM engine
Packages
| Package | Description |
|---|---|
| @docmentis/udoc-viewer | Document viewer SDK (npm package) |
| @docmentis/udoc-viewer-demo | Demo application |
Supported Formats
| Format | Extensions |
|---|---|
| DOCX | .docx |
| PPTX | .pptx |
| Images | .png, .jpg, .jpeg, .gif, .webp, .bmp, .tif, .tiff, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi |
Quick Start
Install
npm install @docmentis/udoc-viewer
Basic Usage
import { UDocClient } from "@docmentis/udoc-viewer";
// Create a client (loads the WASM engine)
const client = await UDocClient.create();
// Create a viewer attached to a container element
const viewer = await client.createViewer({
container: "#viewer",
});
// Load a document
await viewer.load("https://example.com/document.pdf");
// Clean up when done
viewer.destroy();
client.destroy();
HTML
<div id="viewer" style="width: 100%; height: 600px;"></div>
<script type="module">
import { UDocClient } from "@docmentis/udoc-viewer";
const client = await UDocClient.create();
const viewer = await client.createViewer({ container: "#viewer" });
await viewer.load("/path/to/document.pdf");
</script>
React
import { useEffect, useRef } from "react";
import { UDocClient } from "@docmentis/udoc-viewer";
function DocumentViewer({ src }) {
const containerRef = useRef(null);
useEffect(() => {
let client, viewer;
(async () => {
client = await UDocClient.create();
viewer = await client.createViewer({
container: containerRef.current,
});
await viewer.load(src);
})();
return () => {
viewer?.destroy();
client?.destroy();
};
}, [src]);
return <div ref={containerRef} style={{ width: "100%", height: "600px" }} />;
}
Examples
Working examples for every major framework:
| Example | Stack | Run |
|---|---|---|
| vanilla | TypeScript + Vite | npm run dev |
| react-vite | React + Vite | npm run dev |
| vue-vite | Vue + Vite | npm run dev |
| svelte-vite | Svelte 5 + Vite | npm run dev |
| angular | Angular 19 | npm run dev |
| nextjs-webpack | Next.js + Webpack | npm run dev |
| nextjs-turbopack | Next.js + Turbopack | npm run dev |
| nuxt | Nuxt 3 | npm run dev |
cd examples/react-vite
npm install
npm run dev
Features
- Multi-format rendering — PDF, DOCX, PPTX, and images in one unified viewer
- High-fidelity output — custom Rust rendering engine compiled to WebAssembly
- Zoom & navigation — toolbar with zoom controls, page thumbnails, and keyboard navigation
- Full-text search — search with match highlighting and navigation
- Dark mode — built-in light/dark theme with system preference support
- Customizable — override colors and styles via CSS variables
- Responsive — works on desktop and mobile browsers
- Streaming — pages render progressively as the document loads
- Private — documents never leave the browser; no server upload required
How It Works
udoc-viewer uses a custom document processing engine written in Rust, compiled to WebAssembly. Documents are parsed and rendered entirely in the browser with near-native performance — no PDF.js, no iframe hacks, no server-side conversion.
The JavaScript wrapper (@docmentis/udoc-viewer) is MIT-licensed and open source. The WASM rendering engine is free to use, including in commercial applications. See LICENSE for details.
Browser Support
| Browser | Supported |
|---|---|
| Chrome / Edge | 80+ |
| Firefox | 80+ |
| Safari | 15+ |
Requires WebAssembly support.
Telemetry
udoc-viewer collects anonymous, non-personally-identifiable usage data to help us understand SDK adoption and prioritize format support. Telemetry fires once per document open.
What we collect:
| Field | Description | Example |
|---|---|---|
domain |
Hostname of the embedding website | example.com |
format |
Document format | pdf |
size_bucket |
File size in units of 100 KB (floor(bytes / 100000)) |
3 |
viewer_version |
SDK version string | 0.5.19 |
license_hash |
SHA-256 hash of the license key (empty if none) | a1b2c3... |
distinct_id |
Anonymous random UUID stored in localStorage | f47ac10b-... |
What we do NOT collect:
- Document content, filenames, or URLs
- User identity, cookies, or session data (the UUID above is random and not linked to any account)
- IP addresses (disabled at the collection endpoint)
- Any other personally identifiable information
Opting out
Telemetry can be disabled with a license that includes the no_telemetry feature:
const client = await UDocClient.create({
license: "eyJ2Ijox...",
disableTelemetry: true,
});
Without a qualifying license the flag is silently ignored and a warning is logged to the console. To obtain a license, contact licensing@docmentis.com.
Branding & Attribution
udoc-viewer is free to use, including in commercial applications. A "Powered by docMentis" attribution link is shown by default.
To remove the attribution, contact licensing@docmentis.com to obtain a license key, then pass it when creating the client:
const client = await UDocClient.create({ license: "eyJ2Ijox..." });
const viewer = await client.createViewer({
container: "#viewer",
hideAttribution: true,
});
The hideAttribution option is only honored when the license includes the no_attribution feature. Without a valid license, the attribution link will remain visible.
Development
# Install dependencies
npm install
# Build all packages
npm run build
# Run demo (localhost:5173)
npm run dev -w @docmentis/udoc-viewer-demo
Updating the WASM engine
The WASM binary is pre-built from the private docmentis-udoc repository and checked into this repo. To update it after a new Rust build:
# In the docmentis-udoc repo
just push-wasm
Contributing
We welcome bug reports, feature requests, and pull requests. Please read the Contributing Guide before submitting a PR.
- Contributing Guide: CONTRIBUTING.md
- Issues: github.com/docmentis/docmentis-udoc-viewer/issues
- Discussions: github.com/docmentis/docmentis-udoc-viewer/discussions
- Security: SECURITY.md
License
The JavaScript/TypeScript source code is licensed under the MIT License.
The WebAssembly binary (packages/udoc-viewer/src/wasm/udoc_bg.wasm) is distributed under the docMentis WASM Runtime License. It is free to use with the docMentis Viewer in commercial and non-commercial applications.