← DOCX live examples

API reference

DOCX

Public options and methods. For rendering modes, model ownership, and optional renderers, see Production decisions.

Options & methods

Public options and methods. Types omitted for brevity are exported from the package.

DocxViewer

Single-canvas viewer that paginates the document and tracks the current page.

new DocxViewer(canvas: HTMLCanvasElement, options?: DocxViewerOptions)

Options

NameTypeDefaultDescription
Properties
width number Canvas CSS width in px; height is auto-computed from the page aspect ratio.
dpr number devicePixelRatio Device pixel ratio for the backing store (crispness on HiDPI).
useGoogleFonts boolean false Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy.
password string undefined Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded.
enableTextSelection boolean false Overlay a transparent text layer for native selection & copy.
showTrackedChanges boolean false Select the tracked-change markup layout from the initial load. Insertions use author-coloured underlines, deletions use author-coloured strikethroughs, and changed lines receive margin bars. Because this changes line breaks and pagination, set the initial view here and use setLayoutView() or setShowTrackedChanges() for later changes.
currentDate Date | number load time Date used to resolve DATE and TIME fields. It participates in the retained layout variant, so pass it at load time when deterministic field values or pagination are required.
enableElementSelection boolean false Enable read-only picture, chart, and shape selection with a non-editable outline and element context. No editor model is added.
findHighlightColors { match?: string; active?: string } yellow / orange CSS backgrounds for ordinary and active find matches. Values are applied verbatim; use an alpha color to keep the canvas text visible through the overlay.
maxZipEntryBytes number resource policy default Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default.
resourceLimits OoxmlResourceLimits 128 MiB per entry / 256 MiB distinct total / 4,096 entries Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields →
imageResources ImageResourceOptions { decodedByteBudget: 128 MiB, strategy: 'adaptive', resolution: 'native-if-fit' } Decoded-raster policy shared by DOCX, XLSX and PPTX paints. Ordinary browser rasters receive a geometry-weighted share of decodedByteBudget before source extraction, allowing each source to flow directly into decode. A source keeps native resolution when it fits its share and otherwise uses up to a 2x canvas/DPR grid when that share has headroom. If the complete set of display grids exceeds the budget, adaptive mode reduces them by one uniform quality ratio. Set resolution: 'display' to minimize retained pixels. Natural-size consumers, pixel effects that require the authored grid, and non-resizable formats retain their guarded source-specific paths. Set strategy: 'strict' to preserve requested targets and receive OoxmlDecodedImageLimitError on an aggregate crossing. The budget accepts 4 bytes through 512 MiB; encoded-source, per-axis and per-surface hard safety ceilings remain non-disableable. Safety boundaries →
debug boolean false Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection.
math MathRenderer undefined Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation.
threeD ChartThreeDRenderer undefined Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes.
regionMap ChartRegionMapRenderer undefined Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes.
chartEx ChartExRenderer undefined Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes.
tiff TiffRenderer undefined Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes.
mode 'main' | 'worker' 'main' Use 'main' for ordinary previews, the smallest worker download or custom renderer objects. Use 'worker' when rendering larger or more complex documents would compete with scrolling, navigation or other application UI. Worker mode requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Viewer navigation, zoom, virtualized scrolling, selection, find, hyperlinks and the built-in math, ChartEx, 3-D, Region Map and TIFF renderers remain available in both modes.
progressiveLayout boolean false Resolve load() when the opening pages are paintable and continue the same canonical pagination session in the background. While layoutComplete is false, pageCount is the pages available so far rather than the final total. Works in main and worker modes; worker mode also keeps the remaining pagination off the UI thread. Progressive layout guide →
sliceLayout boolean false In main mode, yield to the browser between pagination slices while load() still waits for the complete document. Worker mode already keeps pagination off the UI thread; without progressiveLayout this option has no additional effect there. Use progressiveLayout when opening pages should become available before full pagination finishes. Progressive layout guide →
zoomMin / zoomMax number 0.1 / 4 Zoom factor bounds for setScale / fitWidth / fitPage (10%–400%).
enableHyperlinks boolean true Master switch for hyperlink interactivity. Set false to disable it entirely: no hit-testing, no pointer cursor over links, no default navigation, and onHyperlinkClick is never called. Links still render exactly as authored but are inert, like plain text.
Event handlers
onSelectionContextChange (context: DocxSelectionContext | null) => void Receive bounded detached text or element context. This callback does not enable element hit-testing by itself.
onContextMenu (event: ViewerContextMenuEvent<DocxSelectionContext>) => void Called synchronously for the native contextmenu event. Use originalEvent.preventDefault() before returning to replace the browser menu; getContext() starts one memoized target lookup on first call. Omit the callback to keep native browser behavior unchanged.
onResourceMetrics (metrics: OoxmlResourceMetrics) => void Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results.
onLayoutProgress (progress: Readonly<{ committedUnits: number }>) => void Receive pagination telemetry from resumable layout passes. It implies sliced layout in main mode and is also delivered by progressiveLayout in main or worker mode; a non-progressive worker load does not publish intermediate progress. committedUnits can move backward while convergence revises provisional work; it counts pages, so use pageCount and the Viewer page callbacks for application navigation UI. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutPartial (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void Receive each later provisional page publication after the initial load publication. availableUnits is the pages available so far; totalUnits is omitted until DOCX pagination knows the final count, and exact is currently always false. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutComplete (error?: unknown) => void Called once the authoritative full layout replaces the provisional one, or with the background failure. It fires only when progressiveLayout actually deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onScaleChange (scale: number) => void Called when the zoom factor changes (setScale / fitWidth / fitPage / zoomIn / zoomOut), with the clamped factor (1 = 100%).
onHyperlinkClick (target: HyperlinkTarget) => void Called when a hyperlink is clicked. target is { kind: 'external', url } or { kind: 'internal', ref, slideIndex? }. When supplied, the callback fully owns the click (the default external-open / internal-navigation is not run). External URLs are scheme-sanitized (http / https / mailto / tel only); internal targets resolve to a docx bookmark, pptx slide jump, or xlsx defined name / cell reference. XLSX switches sheets before scrolling the destination into view and uses the first cell of a range.
onPageChange (index: number, total: number, layoutComplete: boolean) => void Called after a page finishes rendering and again when a progressive page-count publication changes total. While layoutComplete is false, total is the pages available so far rather than the final count. Progressive layout guide →
onError (err: Error) => void Receives Viewer-managed failures that have no directly awaitable result, such as virtualized rendering or embedded-media playback. load(), navigation, and other awaitable operations reject their own Promise whether or not this callback is supplied; the same failure is never delivered twice. Background failures are logged with console.error when the callback is omitted. Narrow stable cases with OoxmlError, OoxmlResourceLimitError, OoxmlDecodedImageLimitError or TiffDecodeError; other failures remain Error values and message text is not a stable discriminator. Error reference →

Methods

static fromDocument(canvas, document, options?): Omit<DocxViewer, "load"> Synchronously create a Viewer that borrows an already-loaded document. Render with goToPage(); destroy() leaves the document open.
load(source: string | ArrayBuffer): Promise<void> Load a Viewer-owned URL or ArrayBuffer. With progressiveLayout, resolve when the opening page is paintable while pagination continues in the background.
goToPage(index: number): Promise<void> Render a specific page (0-indexed, clamped). During progressive layout, a requested page beyond the published prefix waits with the loading indicator until it becomes available.
nextPage(): Promise<void> Advance one page.
prevPage(): Promise<void> Go back one page.
setShowTrackedChanges(value: boolean): Promise<void> Switch between the final view (false, default) and the tracked-change markup view (true) at runtime, re-rendering the current page against the selected layout variant.
getScale(): number The current zoom factor (1 = 100%).
setScale(scale: number): Promise<void> Set the absolute zoom factor (1 = 100%), clamped to [zoomMin, zoomMax]; re-renders at the new size and fires onScaleChange when it changes. View-only.
fitWidth(): Promise<void> Fit the content WIDTH to the host container and re-render (routes through setScale). Defers when nothing is loaded or the container is unlaid-out.
fitPage(): Promise<void> Fit the WHOLE content (width and height) inside the container so it is visible without scrolling — takes the tighter of the two fits. Defers when unloaded / unlaid-out.
findText(query: string, opts?: { caseSensitive?: boolean }): Promise<FindMatch<DocxMatchLocation>[]> Full-text search across the whole document; highlights every hit and returns them in document order. Each match carries matchIndex, the matched text, and its location. Case-insensitive by default.
findNext(): Promise<FindMatch<DocxMatchLocation> | null> Move to the next match (wrap-around), navigate to it if needed, and draw it in the active-match colour. Returns the now-active match, or null when there are none. Call findText first.
findPrev(): Promise<FindMatch<DocxMatchLocation> | null> Move to the previous match (wrap-around from first to last).
clearFind(): void Clear all highlights and reset the find state.
get pageCount(): number Pages available so far (0 until loaded); authoritative only when layoutComplete is true.
get currentPage(): number Current page index.
get layoutComplete(): boolean True only after the authoritative document layout succeeds. It is false while progressive layout is publishing pages and remains false if background pagination fails; waitUntilLayoutComplete() reports that failure.
waitUntilLayoutComplete(): Promise<void> Wait for the authoritative full layout before operations that require the final page count. Rejects if background pagination fails after load() resolved.
get canvasElement(): HTMLCanvasElement The underlying canvas.
getSelectionContext(options?: DocxSelectionContextOptions): DocxSelectionContext | null Return the current bounded native-text or clicked-element snapshot. Throws after destroy().
getResourceMetrics(): Promise<OoxmlResourceMetrics> Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output.
destroy(): void Tear down the worker and release resources.

DocxDocument

Headless engine — render any page into any canvas you supply.

await DocxDocument.load(source, options?)

Options

NameTypeDefaultDescription
Properties
useGoogleFonts boolean false Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy.
password string undefined Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded.
wasmUrl string | URL bundled asset Override the URL the parser worker fetches the WebAssembly module from. By default each format resolves the *_parser_bg.wasm asset that ships next to its bundle (relative to the module URL); set this to serve it from a CDN or a self-hosted path instead (a relative value resolves against the document URL). Pointing it at a mismatched or missing file makes load() reject when the worker instantiates it.
maxZipEntryBytes number resource policy default Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default.
resourceLimits OoxmlResourceLimits 128 MiB per entry / 256 MiB distinct total / 4,096 entries Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields →
debug boolean false Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection.
workerTimeoutMs number unlimited Opt-in worker liveness limit. Ordinary worker requests use it as their response deadline. Worker-mode progressive loads restart this silence interval whenever the worker reports progress. This allows active long-running work to continue. Silence before first paint rejects load(); silence afterward keeps layoutComplete false and rejects waitUntilLayoutComplete(), while configured completion/error callbacks receive the failure. Worker exceptions still reject immediately. Unlimited by default.
math MathRenderer undefined Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation.
threeD ChartThreeDRenderer undefined Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes.
regionMap ChartRegionMapRenderer undefined Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes.
chartEx ChartExRenderer undefined Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes.
tiff TiffRenderer undefined Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes.
mode 'main' | 'worker' 'main' Use 'main' for the smallest worker download, the lowest single-frame overhead or custom renderer objects; parsing still runs in a Worker, while Canvas rendering runs on the main thread. Use 'worker' when document layout and paint would compete with application UI responsiveness. It requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Built-in math, ChartEx, 3-D, Region Map and TIFF renderers use the same options in both modes. In worker mode, use the bitmap render methods instead of methods that accept a Canvas.
showTrackedChanges boolean false Select the tracked-change markup layout from the initial load. Insertions use author-coloured underlines, deletions use author-coloured strikethroughs, and changed lines receive margin bars. Because this changes line breaks and pagination, set the initial view here and use setLayoutView() or setShowTrackedChanges() for later changes.
currentDate Date | number load time Date used to resolve DATE and TIME fields. It participates in the retained layout variant, so pass it at load time when deterministic field values or pagination are required.
progressiveLayout boolean false Resolve load() when the opening pages are paintable and continue the same canonical pagination session in the background. While layoutComplete is false, pageCount is the pages available so far rather than the final total. Works in main and worker modes; worker mode also keeps the remaining pagination off the UI thread. Progressive layout guide →
sliceLayout boolean false In main mode, yield to the browser between pagination slices while load() still waits for the complete document. Worker mode already keeps pagination off the UI thread; without progressiveLayout this option has no additional effect there. Use progressiveLayout when opening pages should become available before full pagination finishes. Progressive layout guide →
Event handlers
onResourceMetrics (metrics: OoxmlResourceMetrics) => void Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results.
onLayoutProgress (progress: Readonly<{ committedUnits: number }>) => void Receive pagination telemetry from resumable layout passes. It implies sliced layout in main mode and is also delivered by progressiveLayout in main or worker mode; a non-progressive worker load does not publish intermediate progress. committedUnits can move backward while convergence revises provisional work; it counts pages, so use pageCount and the Viewer page callbacks for application navigation UI. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutPartial (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void Receive each later provisional page publication after the initial load publication. availableUnits is the pages available so far; totalUnits is omitted until DOCX pagination knows the final count, and exact is currently always false. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutComplete (error?: unknown) => void Called once the authoritative full layout replaces the provisional one, or with the background failure. It fires only when progressiveLayout actually deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide →

Methods

static load(source, options?): Promise<DocxDocument> Parse a document from a URL or ArrayBuffer. With progressiveLayout, resolve when the opening pages are paintable while pagination continues in the background.
get comments(): readonly Readonly<DocComment>[] Immutable detached comments and replies stored in the document.
get revisions(): readonly Readonly<DocRevision>[] Immutable detached WordprocessingML body-story insertion, deletion, and move records. This is the current DOCX change-history API, not a cross-format revision contract.
commentAnchorRanges(): readonly CommentAnchorRange[] Logical comment ranges for the currently available page prefix. Await waitUntilLayoutComplete() before treating this as a full-document projection.
getCommentThreads(pageIndex: number, options?: DocxPageCommentThreadsOptions): Promise<readonly Readonly<ResolvedDocxCommentThread>[]> Resolve top-level threads with rendered anchor geometry on one page. Cross-page ranges and repeating stories can occur in more than one page result; each result contains only that page’s rectangles.
revisionAnchorRanges(): readonly RevisionAnchorRange[] Logical tracked-change ranges for the currently available page prefix. Await waitUntilLayoutComplete() before treating this as a full-document projection.
getBookmarkPage(name: string): number | undefined Resolve a bookmark in the currently available page prefix. Await waitUntilLayoutComplete() before concluding that an unresolved name is absent from the document.
collectPageRuns(index, options?): Promise<DocxTextRunInfo[]> Collect the same immutable text-run geometry emitted while rendering one page.
get pageCount(): number Pages available so far; authoritative only when layoutComplete is true.
get layoutComplete(): boolean True only after the authoritative document layout succeeds. It is false while progressive layout is publishing pages and remains false if background pagination fails; waitUntilLayoutComplete() reports that failure.
waitUntilLayoutComplete(): Promise<void> Wait for the authoritative full layout. Rejects if background pagination fails after load() resolved.
pageSize(pageIndex: number): { widthPt, heightPt } Page size in pt for a page (ECMA-376 §17.6.13 / §17.6.11 — per section, so a mixed portrait/landscape document returns different sizes per page). Available in both modes; index is clamped. { 0, 0 } means "not loaded". Returns a fresh object per call.
get mode(): "main" | "worker" The render mode this engine was loaded with. A borrowed engine’s mode decides whether pages render via renderPage (main) or renderPageToBitmap (worker).
setLayoutView(view?: { showTrackedChanges?, currentDate? }): Promise<void> Select the layout variant used by geometry and paint. In worker mode, resolves after matching page metadata is ready and installed atomically.
renderPage(canvas, index, opts?: { width?, dpr?, onTextRun? }): Promise<void> Render one page into the given canvas. onTextRun receives each segment as DocxTextRunInfo, including the authored w14:paraId as paragraphId when present. Unavailable in mode: "worker" — use renderPageToBitmap.
renderPageToBitmap(index, opts?: { width?, dpr?, onTextRun? }): Promise<ImageBitmap> Render one page and return it as an ImageBitmap (both modes; in worker mode page paint, equations, ChartEx, 3-D charts and Region Maps run off the main thread and return the same text-run stream beside the bitmap). The bitmap is caller-owned: pass it to transferFromImageBitmap (which consumes it) or call bitmap.close().
getElementContextAt(pageIndex, point, options?): Promise<DocxElementContext | null> Return compact context for the topmost rendered picture, chart, or shape—including inline content—at a physical-page-point coordinate in either mode.
getResourceMetrics(): Promise<OoxmlResourceMetrics> Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output.
destroy(): void Release the worker.

DocxScrollViewer

Container-owning continuous-scroll viewer. Takes a <div> (not a canvas) and renders the whole document as one vertically-scrolling, virtualized surface (only the visible window + overscan is mounted). Zoom is view-only.

new DocxScrollViewer(container: HTMLElement, options?: DocxScrollViewerOptions)

Options

NameTypeDefaultDescription
Properties
width number container width Base fit width in CSS px. Default: the container width at first non-zero layout.
gap number 16 Vertical gap (px) between consecutive pages.
paddingTop / paddingBottom number gap Desk padding (px) above the first page / below the last. Pass 0 for a flush edge.
paddingLeft / paddingRight number gap Horizontal desk gutters (px); also shrink the container-derived fit width so a page sits inside them at 100%. Pass 0 for a flush edge.
overscan number 1 Pages kept mounted beyond the viewport on each side.
background string undefined CSS background for the scroll surface (the desk behind/between pages). Default transparent (the container shows through).
pageShadow string | false '0 1px 3px rgba(0,0,0,0.2)' CSS box-shadow painted on every page canvas. A spread-only ring (e.g. 0 0 0 1px #c8ccd0) gives a crisp 1px border look. false disables it (flat pages).
enableZoom boolean true Enable Ctrl/⌘ + wheel (and trackpad pinch) zoom. View-only.
zoomMin / zoomMax number 0.1 / 4 Absolute zoom scale bounds (10%–400%). When width fit needs a smaller scale, that fitted scale remains reachable as the effective minimum.
refitOnResize boolean true Re-fit to the container width when it resizes. Set false to preserve an absolute scale independently of viewport width; explicit fitWidth() / fitPage() still work.
enableTextSelection boolean false Overlay a transparent, selectable text layer per page for native copy in both render modes.
showTrackedChanges boolean false Select the tracked-change markup layout from the initial load. Insertions use author-coloured underlines, deletions use author-coloured strikethroughs, and changed lines receive margin bars. Because this changes line breaks and pagination, set the initial view here and use setLayoutView() or setShowTrackedChanges() for later changes.
currentDate Date | number load time Date used to resolve DATE and TIME fields. It participates in the retained layout variant, so pass it at load time when deterministic field values or pagination are required.
comments boolean | DocxCommentsOptions false Show read-only document comment highlights, message icons, and built-in margin cards. Pass cards: false for an application-owned list that retains Viewer-owned range highlighting, or markers: false to hide only the icons. The options object also controls resolved-thread visibility, side, and optional connectors. Theme cards, highlights, and markers with CSS custom properties or documented classes on the Viewer container. Comment UI guide →
enableElementSelection boolean false Enable read-only drawing selection on mounted pages with a non-editable outline and element context.
findHighlightColors { match?: string; active?: string } yellow / orange CSS backgrounds for ordinary and active find matches. Values are applied verbatim; use an alpha color to keep the canvas text visible through the overlay.
enableHyperlinks boolean true Master switch for hyperlink interactivity. Set false to disable it entirely: no hit-testing, no pointer cursor over links, no default navigation, and onHyperlinkClick is never called. Links still render exactly as authored but are inert, like plain text.
useGoogleFonts boolean false Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy.
password string undefined Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded.
maxZipEntryBytes number resource policy default Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default.
resourceLimits OoxmlResourceLimits 128 MiB per entry / 256 MiB distinct total / 4,096 entries Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields →
imageResources ImageResourceOptions { decodedByteBudget: 128 MiB, strategy: 'adaptive', resolution: 'native-if-fit' } Decoded-raster policy shared by DOCX, XLSX and PPTX paints. Ordinary browser rasters receive a geometry-weighted share of decodedByteBudget before source extraction, allowing each source to flow directly into decode. A source keeps native resolution when it fits its share and otherwise uses up to a 2x canvas/DPR grid when that share has headroom. If the complete set of display grids exceeds the budget, adaptive mode reduces them by one uniform quality ratio. Set resolution: 'display' to minimize retained pixels. Natural-size consumers, pixel effects that require the authored grid, and non-resizable formats retain their guarded source-specific paths. Set strategy: 'strict' to preserve requested targets and receive OoxmlDecodedImageLimitError on an aggregate crossing. The budget accepts 4 bytes through 512 MiB; encoded-source, per-axis and per-surface hard safety ceilings remain non-disableable. Safety boundaries →
debug boolean false Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection.
math MathRenderer undefined Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation.
threeD ChartThreeDRenderer undefined Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes.
regionMap ChartRegionMapRenderer undefined Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes.
chartEx ChartExRenderer undefined Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes.
tiff TiffRenderer undefined Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes.
dpr number devicePixelRatio Device pixel ratio for the backing store (crispness on HiDPI).
mode 'main' | 'worker' 'main' Use 'main' for the smallest worker download, the lowest single-frame overhead or custom renderer objects; parsing still runs in a Worker, while Canvas rendering runs on the main thread. Use 'worker' when document layout and paint would compete with application UI responsiveness. It requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Built-in math, ChartEx, 3-D, Region Map and TIFF renderers use the same options in both modes. In worker mode, use the bitmap render methods instead of methods that accept a Canvas.
progressiveLayout boolean false Resolve load() when the opening pages are paintable and continue the same canonical pagination session in the background. While layoutComplete is false, pageCount is the pages available so far rather than the final total. Works in main and worker modes; worker mode also keeps the remaining pagination off the UI thread. Progressive layout guide →
sliceLayout boolean false In main mode, yield to the browser between pagination slices while load() still waits for the complete document. Worker mode already keeps pagination off the UI thread; without progressiveLayout this option has no additional effect there. Use progressiveLayout when opening pages should become available before full pagination finishes. Progressive layout guide →
Event handlers
onSelectionContextChange (context: DocxSelectionContext | null) => void Receive bounded detached text, selected-comment, or element context for external AI/MCP integrations. This callback does not enable element hit-testing.
onContextMenu (event: ViewerContextMenuEvent<DocxSelectionContext>) => void Called synchronously for the native contextmenu event. Use originalEvent.preventDefault() before returning to replace the browser menu; getContext() starts one memoized target lookup on first call. Omit the callback to keep native browser behavior unchanged.
onHyperlinkClick (target: HyperlinkTarget) => void Called when a hyperlink is clicked. target is { kind: 'external', url } or { kind: 'internal', ref, slideIndex? }. When supplied, the callback fully owns the click (the default external-open / internal-navigation is not run). External URLs are scheme-sanitized (http / https / mailto / tel only); internal targets resolve to a docx bookmark, pptx slide jump, or xlsx defined name / cell reference. XLSX switches sheets before scrolling the destination into view and uses the first cell of a range.
onResourceMetrics (metrics: OoxmlResourceMetrics) => void Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results.
onLayoutProgress (progress: Readonly<{ committedUnits: number }>) => void Receive pagination telemetry from resumable layout passes. It implies sliced layout in main mode and is also delivered by progressiveLayout in main or worker mode; a non-progressive worker load does not publish intermediate progress. committedUnits can move backward while convergence revises provisional work; it counts pages, so use pageCount and the Viewer page callbacks for application navigation UI. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutPartial (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void Receive each later provisional page publication after the initial load publication. availableUnits is the pages available so far; totalUnits is omitted until DOCX pagination knows the final count, and exact is currently always false. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onLayoutComplete (error?: unknown) => void Called once the authoritative full layout replaces the provisional one, or with the background failure. It fires only when progressiveLayout actually deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide →
onVisiblePageChange (topIndex: number, total: number, layoutComplete: boolean) => void Fires when the top-most visible page changes and again when a progressive page-count publication changes total, even if the same page remains visible. While layoutComplete is false, total is the pages available so far rather than the final count. Progressive layout guide →
onError (err: Error) => void Receives Viewer-managed failures that have no directly awaitable result, such as virtualized rendering or embedded-media playback. load(), navigation, and other awaitable operations reject their own Promise whether or not this callback is supplied; the same failure is never delivered twice. Background failures are logged with console.error when the callback is omitted. Narrow stable cases with OoxmlError, OoxmlResourceLimitError, OoxmlDecodedImageLimitError or TiffDecodeError; other failures remain Error values and message text is not a stable discriminator. Error reference →

Methods

static fromDocument(container, document, options?): Omit<DocxScrollViewer, "load"> Synchronously create a Scroll Viewer that borrows one loaded document and lays out its initial virtual window.
load(source: string | ArrayBuffer): Promise<void> Load a Viewer-owned document. With progressiveLayout, resolve when the opening window is paintable and grow the scroll surface as pagination continues.
scrollToPage(index: number, opts?: { behavior?: "auto" | "smooth" }): void Scroll so page index’s top edge sits at the viewport top (index clamped).
goToComment(commentId: string, opts?: { pageIndex?: number; behavior?: "auto" | "smooth" }): Promise<boolean> Reveal and highlight a top-level DOCX comment. Omit pageIndex for its first rendered occurrence, or pass the page returned by getCommentThreads() to select that specific occurrence. Returns false when the locator has no rendered anchor.
setShowTrackedChanges(value: boolean): Promise<void> Switch between the final view (false, default) and the tracked-change markup view (true) at runtime. Resolves after matching layout geometry is ready and mounted pages have been refreshed.
findText(query: string, opts?: { caseSensitive?: boolean }): Promise<FindMatch<DocxMatchLocation>[]> Full-text search across the whole document; highlights every hit and returns them in document order. Each match carries matchIndex, the matched text, and its location. Case-insensitive by default.
findNext(): Promise<FindMatch<DocxMatchLocation> | null> Move to the next match (wrap-around), navigate to it if needed, and draw it in the active-match colour. Returns the now-active match, or null when there are none. Call findText first.
findPrev(): Promise<FindMatch<DocxMatchLocation> | null> Move to the previous match (wrap-around from first to last).
clearFind(): void Clear all highlights and reset the find state.
setScale(scale: number): void Set the absolute zoom scale at runtime (clamped to the effective zoom range, which includes a width fit below zoomMin). Flicker-free. View-only.
relayout(): void Force a re-fit + re-mount of the visible window. Called automatically after load / resize / zoom; use it when the container resizes in a way a ResizeObserver cannot observe (e.g. a late web-font load). Idempotent.
get pageCount(): number Pages available so far (0 until loaded); authoritative only when layoutComplete is true.
get topVisiblePage(): number Index of the top-most visible page.
get layoutComplete(): boolean True only after the authoritative document layout succeeds. It is false while progressive layout is publishing pages and remains false if background pagination fails; waitUntilLayoutComplete() reports that failure.
waitUntilLayoutComplete(): Promise<void> Wait for the authoritative full layout before operations that require the final page count. Rejects if background pagination fails after load() resolved.
getSelectionContext(options?: DocxSelectionContextOptions): DocxSelectionContext | null Return the current mounted text selection, selected comment thread, or clicked-element context.
getResourceMetrics(): Promise<OoxmlResourceMetrics> Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output.
destroy(): void Tear down the DOM subtree. Destroys a self-loaded engine; a borrowed one is left intact.

Review data

Comments Read comments stored in Office files, use the built-in UI, or connect an application-owned list to its authored targets.
Comments guide →

Office revision records

Available for DOCX. DocxDocument exposes read-only insertion, deletion, and move records stored in the WordprocessingML document.

You canRead detached records, inspect author/date/text metadata, and resolve their location against a rendered page.

You cannotAccept, reject, or edit changes, or ask the built-in Viewer to render Word-style revision markup.

Use the records

Read document.revisions for an application-owned list. Call revisionAnchorRanges(), collectPageRuns(), and resolveRevisionAnchorRuns() only when that list must point to visible page content.

import {
  DocxDocument,
  resolveRevisionAnchorRuns,
} from '@silurus/ooxml/docx';

const document = await DocxDocument.load(source);
const revisions = document.revisions;

// Add visible page geometry only when your UI needs it.
const ranges = document.revisionAnchorRanges();
const runs = await document.collectPageRuns(pageIndex, { width: 760 });
const changesOnPage = ranges.flatMap((range) => {
  const revision = revisions[range.revisionIndex];
  if (!revision) return [];
  const targets = resolveRevisionAnchorRuns(range, runs);
  return targets.length > 0 ? [{ revision, targets }] : [];
});

renderChangeList(changesOnPage);
document.destroy();

renderChangeList() is application code. The renderer shows the accepted-final document: insertions and move destinations have their own geometry, while deletions and move sources resolve to a nearby final-state position.