npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iamjariwala/react-doc-viewer

v1.9.0

Published

React document viewer with PDF tools, local DOCX and XLSX previews, images, text and pluggable renderers. Other Office formats can use Microsoft Office Online.

Readme

npm version npm downloads npm total downloads bundle size license TypeScript React PRs Welcome GitHub stars

@iamjariwala/react-doc-viewer

A React document viewer with PDF tools, local DOCX and XLSX previews, and pluggable renderers. View PDF, images, CSV, text, Markdown and video; add PDF search, annotations, thumbnails and dark mode. Office preview behavior varies by format—see Supported File Types.

One component, explicit format support, TypeScript APIs.

npm install @iamjariwala/react-doc-viewer
import DocViewer, { DocViewerRenderers } from "@iamjariwala/react-doc-viewer";
import "@iamjariwala/react-doc-viewer/dist/index.css";

<DocViewer
  documents={[{ uri: "https://example.com/sample.pdf" }]}
  pluginRenderers={DocViewerRenderers}
/>;

Live Demo (Storybook) | npm | GitHub


Why @iamjariwala/react-doc-viewer?

Use one viewer API for multiple document formats, with these built-in tools:

  • 20+ file types in a single <DocViewer /> component -- no need to install separate libraries for PDF, images, CSV, video, etc.
  • Dark Mode -- built-in light/dark/auto theme switching with full CSS variable support
  • Text Search -- full-text search across all PDF pages with match highlighting and navigation
  • Annotations -- highlight text, freehand draw, add comments, and export as JSON
  • Keyboard Shortcuts -- navigate pages, zoom, search, print, and fullscreen via keyboard
  • Watermark Overlay -- configurable text watermark with custom opacity, color, size, and rotation
  • Bookmarks / TOC -- auto-extracted PDF outline with nested sidebar navigation
  • Password-Protected PDFs -- built-in password prompt modal for encrypted documents
  • Fullscreen Mode -- one-click fullscreen with keyboard shortcut (F key)
  • Print -- print PDFs directly from the toolbar or via Ctrl+P
  • Split View -- side-by-side document comparison with optional synchronized scrolling
  • Loading Progress -- animated progress bar during PDF loading
  • Text Selection -- select and copy text from PDF pages
  • Drag & Drop -- drop files directly onto the viewer to add or replace documents
  • Thumbnail Sidebar -- visual page navigation with click-to-jump for PDFs
  • Programmatic Control -- jump to any page via ref or prop, navigate documents programmatically
  • 14 Languages -- built-in i18n with community translations
  • Theming & CSS Variables -- full color control via theme object or --rdv-* CSS custom properties
  • Custom Renderers -- extend or replace any file type renderer with your own React component
  • TypeScript First -- complete type definitions, generics, and IntelliSense support
  • Selectable renderers -- choose allowed formats; measure actual bundle output with the included tooling
  • Local DOCX and XLSX previews -- see Security for formats and options that use external services
  • Framework examples -- packed-package checks for Vite and Next.js; see the compatibility notes below

Best for

| Use Case | Why this library | | -------- | ---------------- | | Document Management Systems (DMS) | Preview any uploaded file without leaving the app | | Legal & Compliance Platforms | Annotate, highlight, watermark, and search contracts and filings | | Education & LMS | Display course materials in PDF, DOCX, video, and image formats | | Healthcare & Medical Records | View lab reports, imaging files, and clinical documents with password protection | | Real Estate & Insurance | Preview property documents, claims, and inspection photos with split view compare | | File Browsers & Cloud Storage | Inline file preview for any storage UI with dark mode support | | Internal Tools & Admin Panels | Quick document preview with fullscreen, print, and keyboard shortcuts | | Content Platforms & CMS | Embedded viewer for user-uploaded content with watermark overlay |


How It Compares

Choose based on the formats and controls your application needs. This package combines document navigation and PDF tools with local DOCX and XLSX previews. It is a fork of @cyntler/react-doc-viewer and uses react-pdf internally.

For PDF-only applications, compare the APIs of react-pdf with this package's built-in viewer controls. For other viewers, verify the exact version, required formats, external-service behavior, license and measured consumer bundle before choosing. We do not claim unmeasured size advantages or missing features in competing projects.

See Migration and Performance for reproducible checks.


Feature Highlights

| | | | |:--|:--|:--| | Dark Mode -- Light, dark, and auto theme with CSS variables | Text Search -- Full-text search across all PDF pages | Annotations -- Highlight, draw, and comment on documents | | Keyboard Shortcuts -- Navigate, zoom, search, print via keyboard | Watermark -- Configurable text overlay for confidential docs | Bookmarks / TOC -- Auto-extracted PDF outline sidebar | | Password PDFs -- Built-in password prompt for encrypted files | Fullscreen -- One-click or F-key fullscreen mode | Print -- Print directly from toolbar or Ctrl+P | | Split View -- Side-by-side compare with sync scroll | Thumbnail Sidebar -- Visual page navigation for PDFs | 20+ File Types -- PDF, DOCX, images, video, CSV & more | | Drag & Drop -- Drop files directly onto the viewer | 14 Languages -- Built-in i18n with community translations | Custom Renderers -- Extend or replace any file type |


What's New in v1.9.0

  • Local XLSX table preview with sheet selection, load/error states and documented limits.
  • Clean consumer installation without an install-time npx command.
  • Packed-package validation, runnable examples and reproducible bundle measurements.
  • Synchronized AI documentation with accurate Office rendering and privacy descriptions.

See Release validation and walkthrough, focused guides, and CHANGELOG.

What's New in v1.6.0

  • Common Toolbar for All File Types -- Non-PDF renderers (DOCX, images, text, markdown, RTF, CSV) now have a toolbar with download, print, and zoom controls
  • DOCX Inline Rendering -- Word documents render inline with full formatting using docx-preview-sync instead of download cards
  • DOCX Page Navigation -- Multi-page DOCX documents show page controls (prev/next, page input, jump-to-page) with automatic page detection
  • Markdown Renderer -- Native markdown rendering with headings, lists, links, code blocks, and formatting
  • RTF Renderer -- Rich Text Format file support
  • Search Highlighting -- Text search now highlights matched text with yellow background directly in the PDF
  • Search Page Navigation -- Clicking next/prev match automatically navigates to the page containing the match
  • PDF Scroll Mode Navigation -- Page prev/next buttons now scroll to the correct page in scroll (continuous) mode
  • Sticky Header -- Header bar stays fixed at the top when scrolling through documents
  • Improved Storybook Organization -- Stories reorganized into categorized navigation (Core, Features, File Types, Upload)

What's New in v1.3.0

11 new features that bring the viewer to professional-grade quality:

  • Dark Mode -- themeMode: "light" | "dark" | "auto" with full CSS variable theming and prefers-color-scheme auto-detection
  • Print -- Print button in toolbar, opens PDF in hidden iframe for native print dialog
  • Fullscreen -- Toggle fullscreen from toolbar or keyboard (F key), with proper Escape exit
  • Loading Progress Bar -- Animated progress bar during PDF loading with smooth transitions
  • Watermark Overlay -- Repeated rotated text overlay with configurable opacity, color, size, and rotation
  • Text Selection & Copy -- Enable react-pdf text layer for selecting and copying text from PDF pages
  • Keyboard Shortcuts -- Arrow keys for pages, +/- for zoom, Home/End, Ctrl+F for search, Ctrl+P for print, F for fullscreen
  • Password-Protected PDFs -- Modal password prompt with error feedback for encrypted PDF files
  • Text Search -- Full-text search across all pages using pdfjs, with match count, prev/next navigation, and Ctrl+F shortcut
  • PDF Bookmarks / TOC -- Sidebar with auto-extracted PDF outline (table of contents), nested items, click-to-navigate
  • Split View / Compare -- <SplitDocViewer> component with two viewers side-by-side, draggable divider, and optional scroll sync

Table of Contents

Table of Contents

Supported File Types

@iamjariwala/react-doc-viewer supports 20+ file formats out of the box:

| Extension | MIME Type | Renderer | | --------- | --------- | -------- | | pdf | application/pdf | Full viewer with zoom, pagination, thumbnails, search, bookmarks | | png | image/png | Image with checkerboard background | | jpg / jpeg | image/jpg, image/jpeg | Image viewer | | gif | image/gif | Image viewer (animated GIF support) | | bmp | image/bmp | Image viewer | | tiff | image/tiff | Canvas-based TIFF renderer | | webp | image/webp | Image viewer | | csv | text/csv | Parsed table with configurable delimiter | | txt | text/plain | Monospace text viewer | | htm / html | text/htm, text/html | Sandboxed iframe with DOMPurify sanitization | | mp4 | video/mp4 | Native video player with controls | | md | text/markdown | Parsed markdown with headings, lists, code, links | | rtf | application/rtf | Rich text viewer | | doc | application/msword | Office Online for HTTP(S); download card for local/blob files | | docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Inline rendered with page navigation and formatting | | xls | application/vnd.ms-excel | Office Online for HTTP(S); download card for local/blob files | | xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Local read-only table with sheet navigation | | ppt | application/vnd.ms-powerpoint | Office Online for HTTP(S); download card for local/blob files | | pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | Office Online for HTTP(S); download card for local/blob files | | odt | application/vnd.oasis.opendocument.text | Office Online for HTTP(S); download card for local/blob files |

[!NOTE] DOCX renders inline locally by default; its optional Office Online mode sends the document URL to Microsoft. XLSX renders locally as a read-only table with sheet navigation. DOC, XLS, PPT, PPTX and ODT use Microsoft Office Online for HTTP(S) URLs and download cards for local/blob URLs. Office Online needs a publicly reachable document and does not receive your requestHeaders. Optional server conversion uploads eligible documents to your configured service.

Live Demo

Try all features interactively:

Storybook Demo

Installation

npm install @iamjariwala/react-doc-viewer
yarn add @iamjariwala/react-doc-viewer
pnpm add @iamjariwala/react-doc-viewer
bun add @iamjariwala/react-doc-viewer

Quick Start

import DocViewer, { DocViewerRenderers } from "@iamjariwala/react-doc-viewer";
import "@iamjariwala/react-doc-viewer/dist/index.css";

function App() {
  const docs = [
    { uri: "https://example.com/sample.pdf" },
    { uri: "https://example.com/photo.png" },
  ];

  return <DocViewer documents={docs} pluginRenderers={DocViewerRenderers} />;
}

The CSS import (@iamjariwala/react-doc-viewer/dist/index.css) is required for correct rendering of PDF pages, annotations, thumbnails, and all styled elements.

Framework Guides

Next.js (App Router & Pages Router)

Use a client component and next/dynamic with ssr: false to load the viewer in the browser. "use client" alone does not disable prerendering. See the complete Next.js guide and the runnable packed-package example.

Vite

import DocViewer, { DocViewerRenderers } from "@iamjariwala/react-doc-viewer";
import "@iamjariwala/react-doc-viewer/dist/index.css";

function App() {
  return (
    <DocViewer
      documents={[{ uri: "/sample.pdf" }]}
      pluginRenderers={DocViewerRenderers}
    />
  );
}

Create React App

import DocViewer, { DocViewerRenderers } from "@iamjariwala/react-doc-viewer";
import "@iamjariwala/react-doc-viewer/dist/index.css";

function App() {
  return (
    <DocViewer
      documents={[{ uri: `${process.env.PUBLIC_URL}/sample.pdf` }]}
      pluginRenderers={DocViewerRenderers}
    />
  );
}

Remix

Load browser-dependent viewer code inside a client-only boundary. Keep CSS imports in your framework's supported stylesheet entry. The current package smoke matrix covers Vite and Next.js; verify Remix integration against the version used by your application. See the framework note.

Documents

Remote & Local Files

Each document needs a uri pointing to a file URL or a local file path.

const docs = [
  { uri: "https://example.com/file.pdf" },
  { uri: require("./files/document.pdf") },
];

Initial Active Document

By default the first document is displayed. Use initialActiveDocument to change this:

<DocViewer
  documents={docs}
  initialActiveDocument={docs[1]}
  pluginRenderers={DocViewerRenderers}
/>

Controlled Document

Control which document is displayed with activeDocument and onDocumentChange:

const [activeDocument, setActiveDocument] = useState(docs[0]);

<DocViewer
  documents={docs}
  activeDocument={activeDocument}
  onDocumentChange={setActiveDocument}
  pluginRenderers={DocViewerRenderers}
/>

Blob / Uploaded Files

Create object URLs when selection changes, and revoke them when replacing files or unmounting. Set the real fileType for uploads with a missing/generic MIME type. See the complete upload example and authenticated-file guide.

Renderers

Built-in Renderers

Use all built-in renderers:

import DocViewer, { DocViewerRenderers } from "@iamjariwala/react-doc-viewer";

<DocViewer pluginRenderers={DocViewerRenderers} documents={docs} />;

Or select the renderers your application needs:

import DocViewer, { PDFRenderer, PNGRenderer } from "@iamjariwala/react-doc-viewer";

<DocViewer pluginRenderers={[PDFRenderer, PNGRenderer]} documents={docs} />;

Available renderers: BMPRenderer, CSVRenderer, DocxRenderer, XLSXRenderer, GIFRenderer, HTMLRenderer, JPGRenderer, MarkdownRenderer, MSDocRenderer, PDFRenderer, PNGRenderer, RTFRenderer, TIFFRenderer, TXTRenderer, VideoRenderer, WebPRenderer

Custom Renderer

Create a renderer for any file type by defining fileTypes, weight, and a React component:

import { DocRenderer } from "@iamjariwala/react-doc-viewer";

const MyPNGRenderer: DocRenderer = ({ mainState: { currentDocument } }) => {
  if (!currentDocument) return null;
  return <img src={currentDocument.fileData as string} />;
};

MyPNGRenderer.fileTypes = ["png", "image/png"];
MyPNGRenderer.weight = 1;

<DocViewer pluginRenderers={[MyPNGRenderer]} documents={docs} />;

Custom File Loader

Prevent the default file loading and handle it yourself:

MyPNGRenderer.fileLoader = ({ documentURI, signal, fileLoaderComplete }) => {
  myCustomLoader(documentURI).then(() => {
    fileLoaderComplete();
  });
};

Features

Dark Mode

Switch between light, dark, and auto (system preference) themes. Dark mode applies to the entire viewer including the toolbar, header, sidebars, and modals.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    themeMode: "dark",
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | themeMode | "light" \| "dark" \| "auto" | "light" | "auto" uses prefers-color-scheme media query |

The "auto" mode listens for system theme changes in real-time. All dark mode styles use [data-theme="dark"] CSS selectors, so you can override any element:

#react-doc-viewer[data-theme="dark"] .rdv-pdf-controls {
  background: #1a1a2e;
}

Text Search in PDF

Full-text search across all pages using the pdfjs text extraction API. Matched text is highlighted with a yellow background directly in the PDF. Displays match count with prev/next navigation that automatically jumps to the page containing the match.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    search: { enableSearch: true },
    keyboard: { enableKeyboardShortcuts: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableSearch | boolean | false | Show search icon in toolbar and enable Ctrl+F shortcut |

When enabled, a search icon appears in the toolbar. Click it or press Ctrl+F to open the search bar. Type to search -- matched text is highlighted in yellow directly on the PDF pages. Press Enter to go to the next match (auto-navigates to the correct page), Shift+Enter for the previous match, and Escape to close.

Keyboard Shortcuts

Navigate pages, zoom, search, print, and toggle fullscreen entirely from the keyboard.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    keyboard: { enableKeyboardShortcuts: true },
    search: { enableSearch: true },
    fullscreen: { enableFullscreen: true },
    print: { enablePrint: true },
  }}
/>

| Shortcut | Action | | -------- | ------ | | Arrow Left / Arrow Right | Previous / next page | | Home / End | First / last page | | + or = | Zoom in | | - | Zoom out | | 0 | Reset zoom | | Ctrl+F | Open text search (requires search.enableSearch) | | Ctrl+P | Print (requires print.enablePrint) | | F | Toggle fullscreen (requires fullscreen.enableFullscreen) | | Escape | Close search / exit fullscreen |

Shortcuts are automatically disabled when focus is inside an input, textarea, or select element.

Watermark Overlay

Add a configurable text watermark overlay to every PDF page. The watermark is rendered as a non-interactive CSS grid of repeated rotated text.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    watermark: {
      text: "CONFIDENTIAL",
      opacity: 0.08,
      fontSize: 52,
      color: "#ff0000",
      rotation: -35,
    },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | text | string | (required) | Watermark text to display | | opacity | number | 0.1 | Opacity (0 to 1) | | fontSize | number | 48 | Font size in pixels | | color | string | "#000" | Text color | | rotation | number | -30 | Rotation angle in degrees |

The watermark has pointer-events: none so it never blocks interaction with the document.

PDF Bookmarks / TOC Sidebar

Automatically extract and display the PDF's table of contents (outline) in a collapsible sidebar. Nested bookmark items are supported with indentation.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    bookmarks: { enableBookmarks: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableBookmarks | boolean | false | Show bookmarks icon in toolbar |

When enabled, a bookmarks icon appears in the toolbar. Click to toggle the sidebar. Each bookmark navigates to its target page. If the PDF has no outline, an empty state message is shown.

Password-Protected PDFs

Display a password prompt modal when a PDF file is encrypted. The user enters their password to decrypt and view the document.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    password: { enablePasswordPrompt: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enablePasswordPrompt | boolean | false | Show password modal for encrypted PDFs |

When disabled, encrypted PDFs will fail to load silently. When enabled, a styled modal with a lock icon, password input, and error feedback appears.

Fullscreen Mode

Toggle fullscreen viewing from the toolbar or keyboard. The entire PDF container (including toolbar and sidebars) enters fullscreen.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    fullscreen: { enableFullscreen: true },
    keyboard: { enableKeyboardShortcuts: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableFullscreen | boolean | false | Show fullscreen icon in toolbar and enable F shortcut |

Press F to toggle fullscreen, Escape to exit. The fullscreen icon in the toolbar dynamically switches between enter/exit icons.

Print

Print the current PDF document directly from the toolbar. Opens the browser's native print dialog.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    print: { enablePrint: true },
    keyboard: { enableKeyboardShortcuts: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enablePrint | boolean | false | Show print icon in toolbar and enable Ctrl+P shortcut |

The print feature creates a hidden iframe with the PDF, loads it, and triggers window.print() for the native print dialog. Print media CSS automatically hides the toolbar and sidebars.

Split View / Compare

Compare two documents side-by-side with an independent <SplitDocViewer> component. Each side has its own DocViewer instance with independent navigation, zoom, and controls.

import { SplitDocViewer } from "@iamjariwala/react-doc-viewer";
import "@iamjariwala/react-doc-viewer/dist/index.css";

<SplitDocViewer
  left={{
    documents: [{ uri: "/document-v1.pdf" }],
    config: { pdfVerticalScrollByDefault: true },
  }}
  right={{
    documents: [{ uri: "/document-v2.pdf" }],
    config: { pdfVerticalScrollByDefault: true },
  }}
  syncScroll={true}
/>

| Prop | Type | Description | | ---- | ---- | ----------- | | left | { documents, config?, pluginRenderers?, ... } | Props for the left DocViewer instance | | right | { documents, config?, pluginRenderers?, ... } | Props for the right DocViewer instance | | syncScroll | boolean | When true, scrolling one side scrolls the other |

The divider between panels is draggable to resize. SplitDocViewer is exported directly from the package:

import { SplitDocViewer } from "@iamjariwala/react-doc-viewer";

Loading Progress Bar

Display an animated progress bar while PDF documents are loading. Shows actual load progress from the PDF.js library.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    loadingProgress: { enableProgressBar: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableProgressBar | boolean | false | Show progress bar during PDF loading |

The progress bar appears at the top of the PDF area and smoothly animates from 0% to 100% as the PDF loads.

Text Selection & Copy

Enable the react-pdf text layer so users can select and copy text from PDF pages.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    textSelection: { enableTextSelection: true },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableTextSelection | boolean | false | Render PDF text layer for selection and copying |

When enabled, text on PDF pages becomes selectable. Use Ctrl+C / Cmd+C to copy selected text.

Drag & Drop File Upload

Enable file drag-and-drop to add or replace documents in the viewer. Supports file type filtering, size limits, and callbacks.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    dragDrop: {
      enableDragDrop: true,
      acceptedFileTypes: ["application/pdf", "image/*"],
      maxFileSize: 50 * 1024 * 1024, // 50 MB
      dropBehavior: "append",
      onDrop: (files) => {
        console.log("Files dropped:", files);
      },
      onDropRejected: (files, reason) => {
        console.log("Rejected:", reason);
      },
    },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableDragDrop | boolean | false | Enable drag-and-drop | | acceptedFileTypes | string[] | all types | MIME types to accept (supports wildcards like image/*) | | maxFileSize | number | unlimited | Max file size in bytes | | dropBehavior | "append" \| "replace" | "append" | Add to or replace existing documents | | onDrop | (files: File[]) => void | -- | Callback when files are accepted | | onDropRejected | (files: File[], reason: "file-type" \| "file-size" \| "unknown") => void | -- | Callback when files are rejected |

Thumbnail Sidebar

Display a visual sidebar with page thumbnails for quick PDF navigation. Click any thumbnail to jump to that page.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    thumbnail: {
      enableThumbnails: true,
      thumbnailWidth: 120,
      sidebarDefaultOpen: true,
    },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableThumbnails | boolean | false | Enable thumbnail sidebar | | thumbnailWidth | number | 120 | Width of each thumbnail in pixels | | sidebarDefaultOpen | boolean | false | Open sidebar by default |

Annotations (Highlight, Draw, Comment)

Add highlights, freehand drawings, and comments to your documents. Export annotations as JSON for persistence.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    annotations: {
      enableAnnotations: true,
      defaultColor: "#FFFF00",
      colors: ["#FFFF00", "#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4"],
      tools: ["select", "highlight", "pen", "comment", "eraser"],
      onAnnotationChange: (annotations) => {
        console.log("Annotations:", annotations);
      },
      initialAnnotations: [],
    },
  }}
/>

| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | enableAnnotations | boolean | false | Enable annotation toolbar | | defaultColor | string | -- | Default color for new annotations | | colors | string[] | -- | Color palette for the picker | | tools | AnnotationTool[] | all | Which tools to show: "select", "highlight", "pen", "comment", "eraser" | | onAnnotationChange | (annotations: IAnnotation[]) => void | -- | Callback when annotations change | | initialAnnotations | IAnnotation[] | [] | Pre-loaded annotations |

Exporting annotations -- Use the useAnnotationExport hook:

import { useAnnotationExport } from "@iamjariwala/react-doc-viewer";

function AnnotationControls() {
  const {
    exportAnnotations,
    exportAsJSON,
    downloadAnnotations,
    getAnnotationsForPage,
    annotationCount,
  } = useAnnotationExport();

  return (
    <button onClick={() => downloadAnnotations("my-annotations.json")}>
      Download {annotationCount} Annotations
    </button>
  );
}

Page Navigation & Page Jump

Jump to a specific page using a ref or the jumpToPage prop.

Using ref:

import DocViewer, { DocViewerRef } from "@iamjariwala/react-doc-viewer";

const docViewerRef = useRef<DocViewerRef>(null);

<DocViewer ref={docViewerRef} documents={docs} pluginRenderers={DocViewerRenderers} />;

docViewerRef.current?.goToPage(5);
docViewerRef.current?.prev();
docViewerRef.current?.next();

Using the jumpToPage prop:

const [page, setPage] = useState(1);

<DocViewer documents={docs} pluginRenderers={DocViewerRenderers} jumpToPage={page} />;

Configuration

Full Config Reference

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    // Header
    header: {
      disableHeader: false,
      disableFileName: false,
      retainURLParams: false,
      overrideComponent: MyHeader,
    },
    // Loading & error
    loadingRenderer: {
      overrideComponent: MyLoader,
      showLoadingTimeout: 500,
    },
    noRenderer: {
      overrideComponent: MyError,
    },
    // PDF options
    csvDelimiter: ",",
    pdfZoom: {
      defaultZoom: 1.1,
      zoomJump: 0.2,
    },
    pdfVerticalScrollByDefault: true,
    // Theme
    themeMode: "dark",             // "light" | "dark" | "auto"
    // PDF features
    print: { enablePrint: true },
    fullscreen: { enableFullscreen: true },
    loadingProgress: { enableProgressBar: true },
    watermark: {
      text: "CONFIDENTIAL",
      opacity: 0.08,
      fontSize: 52,
      color: "#ff0000",
      rotation: -35,
    },
    textSelection: { enableTextSelection: true },
    keyboard: { enableKeyboardShortcuts: true },
    password: { enablePasswordPrompt: true },
    search: { enableSearch: true },
    bookmarks: { enableBookmarks: true },
    // Existing features
    dragDrop: {
      enableDragDrop: true,
      acceptedFileTypes: ["application/pdf", "image/*"],
      maxFileSize: 50 * 1024 * 1024,
      dropBehavior: "append",
      onDrop: (files) => console.log(files),
      onDropRejected: (files, reason) => console.log(reason),
    },
    thumbnail: {
      enableThumbnails: true,
      thumbnailWidth: 120,
      sidebarDefaultOpen: false,
    },
    annotations: {
      enableAnnotations: true,
      defaultColor: "#FFFF00",
      colors: ["#FFFF00", "#FF6B6B", "#4ECDC4"],
      tools: ["select", "highlight", "pen", "comment", "eraser"],
      onAnnotationChange: (annotations) => console.log(annotations),
      initialAnnotations: [],
    },
  }}
/>

Overriding Header

import { IHeaderOverride } from "@iamjariwala/react-doc-viewer";

const MyHeader: IHeaderOverride = (state, previousDocument, nextDocument) => {
  if (!state.currentDocument) return null;

  return (
    <div>
      <span>{state.currentDocument.uri}</span>
      <button onClick={previousDocument} disabled={state.currentFileNo === 0}>
        Prev
      </button>
      <button
        onClick={nextDocument}
        disabled={state.currentFileNo >= state.documents.length - 1}
      >
        Next
      </button>
    </div>
  );
};

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{ header: { overrideComponent: MyHeader } }}
/>;

Overriding Loading Renderer

const MyLoader = ({ document, fileName }: { document: IDocument | undefined; fileName: string }) => {
  return <div>Loading {fileName || document?.fileType}...</div>;
};

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{
    loadingRenderer: {
      overrideComponent: MyLoader,
      showLoadingTimeout: 500,
    },
  }}
/>;

Overriding No Renderer (Error)

const MyError = ({ document, fileName }: { document: IDocument | undefined; fileName: string }) => {
  return <div>Unsupported file: {fileName || document?.fileType}</div>;
};

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  config={{ noRenderer: { overrideComponent: MyError } }}
/>;

Theming & CSS Variables

Customize the viewer's appearance with a theme object. Values are injected as CSS custom properties (--rdv-*) on the container element.

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  theme={{
    primary: "#5296d8",
    secondary: "#ffffff",
    tertiary: "#5296d899",
    textPrimary: "#ffffff",
    textSecondary: "#5296d8",
    textTertiary: "#00000099",
    disableThemeScrollbar: false,
  }}
/>

| Property | CSS Variable | Default | Description | | -------- | ------------ | ------- | ----------- | | primary | --rdv-primary | "#fff" | Primary background color | | secondary | --rdv-secondary | "#000" | Secondary background color | | tertiary | --rdv-tertiary | "#ffffff99" | Tertiary background color | | textPrimary | --rdv-text-primary | "#000" | Primary text color | | textSecondary | --rdv-text-secondary | "#fff" | Secondary text color | | textTertiary | --rdv-text-tertiary | "#00000044" | Tertiary text color | | disableThemeScrollbar | -- | false | Disable themed scrollbar styling |

Styling & CSS Customization

CSS class:

<DocViewer documents={docs} pluginRenderers={DocViewerRenderers} className="my-viewer" />

Inline styles:

<DocViewer documents={docs} pluginRenderers={DocViewerRenderers} style={{ width: 500, height: 500 }} />

Override internal elements with CSS classes:

All internal elements use .rdv-* class names that you can target:

.rdv-container {
  border-radius: 10px;
}

.rdv-header-bar {
  background-color: #faf;
}

.rdv-pdf-controls {
  gap: 12px;
}

Override CSS custom properties globally:

#react-doc-viewer {
  --rdv-primary: #1a1a2e;
  --rdv-secondary: #16213e;
  --rdv-text-primary: #e94560;
}

Common CSS class reference:

| Class | Element | | ----- | ------- | | .rdv-container | Root container | | .rdv-header-bar | Top header bar | | .rdv-file-name | File name display | | .rdv-doc-nav-prev / .rdv-doc-nav-next | Document navigation buttons | | .rdv-pdf-controls | PDF control bar (zoom, pagination) | | .rdv-pdf-page-wrapper | Individual PDF page wrapper | | .rdv-pdf-progress-bar | Loading progress bar container | | .rdv-pdf-progress-fill | Loading progress bar fill | | .rdv-thumbnail-sidebar | Thumbnail sidebar container | | .rdv-annotation-toolbar | Annotation toolbar | | .rdv-search-bar | Text search floating bar | | .rdv-bookmarks-sidebar | Bookmarks / TOC sidebar | | .rdv-password-overlay | Password prompt overlay | | .rdv-password-modal | Password prompt modal | | .rdv-watermark-overlay | Watermark overlay container | | .rdv-split-container | Split view container | | .rdv-split-panel | Split view panel | | .rdv-split-divider | Split view draggable divider | | .rdv-image-container | Image renderer container | | .rdv-csv-container | CSV table container | | .rdv-txt-container | Text renderer container | | .rdv-video-container | Video player container | | .rdv-msdoc-container | Office document download card | | .rdv-loading-container | Loading spinner container |

Internationalization (i18n) -- 14 Languages

Pass a language prop to translate the UI into any of the 14 supported languages:

<DocViewer documents={docs} pluginRenderers={DocViewerRenderers} language="pl" />

Supported languages:

| Code | Language | Code | Language | | ---- | -------- | ---- | -------- | | en | English | ja | Japanese | | ar | Arabic | pl | Polish | | de | German | pt | Portuguese | | es | Spanish | ru | Russian | | fr | French | se | Swedish | | it | Italian | sr | Serbian (Latin) | | tr | Turkish | sr_cyr | Serbian (Cyrillic) |

Translation files are in src/locales/. PRs for new languages are welcome.

Performance & Bundle Size

Run npm run measure:bundle after building to measure minified and gzip assets for real consumer bundles. See Performance for the exact methodology and limitations. Selective renderer imports control accepted formats; they do not guarantee that all shared PDF dependencies disappear from a bundle.

The XLSX parser loads on demand. Spreadsheet preview has explicit input and display limits; see XLSX guide.

Security

PDF and XLSX parsing run in the browser. DOCX uses local rendering by default. Other Office formats may use Microsoft Office Online, and optional server conversion uploads documents to your configured service. Remote documents and embedded resources can still make network requests. See Security.

  • HTML and Markdown output use DOMPurify; sanitization is not a guarantee against every attack or network request. Apply your application's content policy and keep dependencies updated.
  • For confidential Office files, pass only local renderers (DocxRenderer, XLSXRenderer, PDFRenderer, etc.), leave docx.useOfficeOnlineViewer disabled and do not enable serverConversion.
  • XLSX is a data preview, not an Excel execution environment. Formula expressions are not executed; cached values may be displayed. Charts, macros and exact formatting are not supported.
  • Visible watermarks are a visual cue, not access control or DRM.

Advanced

DocViewerRef API

Control the viewer programmatically:

import DocViewer, { DocViewerRef } from "@iamjariwala/react-doc-viewer";

const docViewerRef = useRef<DocViewerRef>(null);

<DocViewer ref={docViewerRef} documents={docs} pluginRenderers={DocViewerRenderers} />;

docViewerRef.current?.prev();
docViewerRef.current?.next();
docViewerRef.current?.goToPage(3);

| Method | Description | | ------ | ----------- | | prev() | Navigate to the previous document | | next() | Navigate to the next document | | goToPage(n) | Jump to page n in the current PDF |

Custom HTTP Verb for S3 / Cloud Storage

Some services (like AWS S3 pre-signed URLs) require a specific HTTP verb for pre-fetching. By default, HEAD is used:

<DocViewer documents={docs} pluginRenderers={DocViewerRenderers} prefetchMethod="GET" />

Custom Request Headers for Authenticated APIs

Provide custom headers for authenticated requests (JWT, API keys, etc.):

<DocViewer
  documents={docs}
  pluginRenderers={DocViewerRenderers}
  prefetchMethod="GET"
  requestHeaders={{
    "X-Access-Token": "1234567890",
    "My-Custom-Header": "value",
  }}
/>

FAQ

What is the best React document viewer library? Choose based on formats, privacy requirements, accessibility, integrations and measured performance. This package is suitable when you want multiple renderers and built-in PDF tools behind one API; no package is the best fit for every application.

How do I display a PDF in React? Install @iamjariwala/react-doc-viewer, import DocViewer and DocViewerRenderers, pass your PDF URL as a document, and the component handles rendering, zoom, pagination, and page navigation automatically. See Quick Start.

How do I display a PDF in Next.js? Load the viewer through a browser-only dynamic import from a client component, import the CSS file, and pass your PDF document. See Next.js guide.

Can I view Word, Excel, and PowerPoint files in React? DOCX renders inline locally by default; its optional Office Online mode sends the document URL to Microsoft. XLSX renders locally as a read-only table with sheet navigation. DOC, XLS, PPT, PPTX and ODT use Microsoft Office Online for HTTP(S) URLs and download cards for local/blob URLs. Office Online needs a publicly reachable document and does not receive your requestHeaders. Optional server conversion uploads eligible documents to your configured service.

Does it support dark mode? Yes. Set config.themeMode to "dark" for dark mode, "light" for light mode, or "auto" to follow the system's prefers-color-scheme preference. Dark mode applies to the toolbar, header, sidebars, modals, and all UI elements.

Does it support text search in PDFs? Yes. Enable config.search.enableSearch to add a search icon to the toolbar. Press Ctrl+F to open the search bar, which searches across all pages with match count and prev/next navigation.

Does it support keyboard shortcuts? Yes. Enable config.keyboard.enableKeyboardShortcuts for arrow key page navigation, +/- zoom, Home/End, Ctrl+F search, Ctrl+P print, F for fullscreen, and Escape to exit.

Can I add a watermark to PDFs? Yes. Set config.watermark with your desired text, opacity, color, font size, and rotation. The watermark appears on every page as a non-interactive overlay.

Does it support password-protected PDFs? Yes. Enable config.password.enablePasswordPrompt to show a password prompt modal when an encrypted PDF is loaded. The user enters their password to decrypt and view the document.

Can I view bookmarks or table of contents in a PDF? Yes. Enable config.bookmarks.enableBookmarks to show a bookmarks sidebar that auto-extracts the PDF's outline with nested items and click-to-navigate.

Can I compare two documents side by side? Yes. Use the <SplitDocViewer> component with left and right props. Each side gets its own DocViewer instance. Optional syncScroll keeps both sides in sync.

Does it support annotations and highlighting? Yes. Enable annotations via config to get text highlighting, freehand drawing, comments, and an eraser tool. Annotations can be exported as JSON and pre-loaded from saved data. See Annotations.

Can I annotate a PDF in React? Yes. Enable config.annotations.enableAnnotations to get a full annotation toolbar with highlighting, freehand drawing, comments, color picker, and eraser. Annotations are per-page and can be exported/imported as JSON.

Does it work with Next.js? The repository validates packed-package Vite consumers and a Next.js example. Use a browser-only boundary for server-rendered applications. Other frameworks need application-level verification. See Framework Guides.

Does it work with Vite? Yes. Import the component and CSS file -- no additional configuration needed. See Vite guide.

Can I add my own file type renderer? Yes. Create a custom renderer component with fileTypes and weight properties and pass it via pluginRenderers. You can also override the file loading logic. See Custom Renderer.

How do I style or theme the document viewer? Use the theme prop for color customization, the className or style props for container styling, or override .rdv-* CSS classes and --rdv-* CSS custom properties for fine-grained control. See Theming and Styling.

Is it secure? Does it send data to external servers? PDF and XLSX parsing run in the browser. DOCX uses local rendering by default. Other Office formats may use Microsoft Office Online, and optional server conversion uploads documents to your configured service. Remote documents and embedded resources can still make network requests. See Security.

How does this compare to react-pdf? react-pdf only handles PDF files. @iamjariwala/react-doc-viewer handles 20+ file types including PDF, and adds dark mode, text search, annotations, keyboard shortcuts, watermarks, bookmarks, password support, fullscreen, print, split view, drag-and-drop, thumbnails, theming, and i18n on top. Compare application bundle measurements and required controls before choosing.

How do I reduce bundle size? Import only the renderers you need (PDFRenderer, PNGRenderer, etc.) instead of DocViewerRenderers. Use React.lazy() to code-split the viewer. See Performance.

Does it support drag-and-drop file upload? Yes. Enable config.dragDrop.enableDragDrop to allow users to drag files onto the viewer. Supports file type filtering, size limits, append/replace behavior, and rejection callbacks. See Drag & Drop.

Does it support thumbnail navigation? Yes. Enable config.thumbnail.enableThumbnails to show a sidebar with page thumbnails for PDFs. Click any thumbnail to jump to that page. See Thumbnail Sidebar.

Can I jump to a specific page in a PDF? Yes. Use docViewerRef.current?.goToPage(5) for programmatic navigation, or the jumpToPage prop for declarative control. See Page Navigation.

Can I print a PDF from the viewer? Yes. Enable config.print.enablePrint to add a print button to the toolbar. Press Ctrl+P with keyboard shortcuts enabled.

Does it support fullscreen mode? Yes. Enable config.fullscreen.enableFullscreen to add a fullscreen button. Press F with keyboard shortcuts enabled.

Does it support TypeScript? Yes. The library is written in TypeScript and ships with complete type definitions. All props, config options, and hooks are fully typed with IntelliSense support.

What React versions are supported? React 17, 18 and 19 are the supported peer major versions. CI checks packed-package consumer builds; this is not a claim that every browser or framework version is tested. See Release validation.

Is it accessible? The viewer uses semantic HTML, keyboard-navigable controls, and appropriate ARIA attributes where applicable.

Migrating from Other Libraries

From @cyntler/react-doc-viewer

@iamjariwala/react-doc-viewer is a fork of @cyntler/react-doc-viewer with additional features. Migration is straightforward:

  1. Replace the package: npm uninstall @cyntler/react-doc-viewer && npm install @iamjariwala/react-doc-viewer
  2. Update imports: replace @cyntler/react-doc-viewer with @iamjariwala/react-doc-viewer
  3. Add the CSS import: import "@iamjariwala/react-doc-viewer/dist/index.css"
  4. Review changed configuration, CSS, Office privacy behavior and renderer exports before migrating

From react-pdf

If you're using react-pdf and need multi-format support:

  1. Install: npm install @iamjariwala/react-doc-viewer
  2. Replace <Document> + <Page> with <DocViewer documents={[{ uri: pdfUrl }]} />
  3. The built-in PDF renderer handles zoom, pagination, and page navigation automatically

From react-file-viewer

  1. Install: npm install @iamjariwala/react-doc-viewer
  2. Replace <FileViewer fileType={type} filePath={path} /> with <DocViewer documents={[{ uri: path }]} />
  3. File type is detected automatically from the URL or can be specified via fileType property

Contributing

Contributions are welcome. Please open an issue first to discuss significant changes. PRs for bug fixes, new renderers, and translations are appreciated.

git clone https://github.com/mehuljariwala/react-doc-viewer.git
cd react-doc-viewer
npm install
npm start

License

Apache-2.0


Forked from @cyntler/react-doc-viewer. Built and maintained by Mehul Jariwala.