react-doc-viewer

A pluggable React component that renders PDFs, images, Office documents, CSVs, HTML, and video in one unified inline viewer.

Library
npm
v1.17.1
480stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
50/100Fair
Development Activity0
Maintenance44
Community72
Maturity56
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
63/100Good
Architecture75
Code Quality60
Innovation55
Learning Curve60

@cyntler/react-doc-viewer is a fork of the abandoned Alcumus react-doc-viewer, revived to keep a single-component document preview solution alive for React 17+ apps. Instead of wiring up a separate viewer for every file type an app might receive, it accepts an array of document objects and picks the right renderer automatically based on file type, falling back to the official Microsoft Office Online viewer (embedded via iframe) for doc/docx/ppt/pptx/xls/xlsx files that have no native browser rendering path.

The renderer selection is pluggable: built-in renderers for PDF (via react-pdf), raster images, CSV (via PapaParse), TXT, HTML, and video each declare a fileTypes list and a weight, and consumers can register their own renderer or override a default one through the pluginRenderers prop. A custom fileLoader callback lets a renderer bypass the library’s own fetch pipeline entirely, which combined with requestHeaders and a configurable prefetchMethod supports previewing files behind authenticated or verb-restricted URLs.

What You Get

  • A single React component covering PDF, image (PNG/JPG/GIF/BMP/TIFF/WebP), CSV, TXT, HTML, video, and Microsoft Office file previews out of the box
  • A weight-based pluggable renderer system so any file type’s default handler can be overridden or extended without forking the library
  • Controlled and uncontrolled navigation between multiple documents, plus an imperative DocViewerRef for programmatic prev/next
  • Support for remote URLs, bundled local files, and in-browser blobs/object URLs (e.g. from a file <input>) with no server round trip required
  • Built-in theming via a theme prop, per-element DOM ids for CSS overrides, and styled-components compatibility
  • Configurable request headers and prefetch HTTP verb for previewing files served from authenticated or verb-restricted APIs

Common Use Cases

  • Previewing user-uploaded attachments (contracts, invoices, spreadsheets) inline in an admin or support dashboard without downloading each file
  • Embedding inline file previews in a CRM, ticketing system, or document-management tool that needs to handle whatever format a user uploads
  • Rendering protected or authenticated documents by supplying custom request headers or a custom file loader for the fetch step
  • Building a lightweight internal document portal where a single component needs to preview PDFs, Office files, and images side by side

Under The Hood

Architecture The entry point src/DocViewer.tsx wraps the tree in a DocViewerProvider (a hand-rolled useReducer store defined across store/mainStateReducer.ts and store/actions.ts, following a Redux-like action/reducer split) and a styled-components ThemeProvider, then renders a HeaderBar and a ProxyRenderer. The useRendererSelector and useDocumentLoader hooks form a distinct business-logic layer between the store and presentation: they resolve which renderer handles the active document (by fileTypes + weight) and manage fetch/loading state respectively, while each format lives in its own folder under src/renderers/ (pdf, image, csv, msdoc, html, video, txt, etc.) implementing a shared DocRenderer interface. This state → hooks → renderer layering is clean and consistently applied, though the weight-based selection contract means every renderer, including third-party custom ones, must agree on how fileTypes/weight collisions resolve.

Tech Stack TypeScript throughout, with React 17+/18 as a peer dependency, styled-components 6.x for theming and CSS-in-JS, react-pdf 9 (pdf.js under the hood) for PDF rendering, PapaParse for CSV parsing, mustache and ajv for templated/validated rendering paths, and a core-js polyfill for Promise.withResolvers. Microsoft Office formats are rendered by delegating to Microsoft’s own Office Online viewer through an iframe rather than any local rendering code. The library is built with Vite plus vite-plugin-dts (emitting ESM and CJS bundles with type declarations and a separate CSS file), documented and demoed via Storybook 8 deployed to GitHub Pages, and released with release-it.

Code Quality Tests run on Vitest with Testing Library and happy-dom, covering component rendering with no documents, multiple document types, an unsupported file type’s fallback message, and initialActiveDocument behavior — useful smoke coverage, but it lives entirely in one file (src/__tests__/index.test.tsx) rather than per-renderer, so many individual renderers (msdoc, video, html) have no dedicated tests. ESLint and Prettier are enforced in CI (.github/workflows/ci.yml runs prettier:check, lint, test, and build on every push/PR to main), and the codebase is fully typed with consistent naming conventions. Error handling is explicit but minimal: a thrown Error for a missing documents prop and a dedicated “No renderer for file type” fallback component.

What Makes It Unique Rather than inventing new rendering technology, its value is in the unification: one component surface for a wide spread of formats — including formats with no native browser renderer, like Office documents — behind a single pluggable, weight-ordered renderer registry that consumers can extend or override per file type, plus a custom file-loader escape hatch for authenticated or non-standard fetch flows. The maintainer has publicly stated they are stopping active development due to lack of time, so the project is functionally feature-complete but not being extended further.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search