React PDF Viewer: Complete guide to building with react-pdf in 2025

Table of contents

    Learn to build a React PDF viewer with the popular react-pdf library and compare it with Nutrient's React PDF library. This guide covers implementation approaches, technical trade-offs, and feature comparisons to help you choose the right solution for your application requirements.
    React PDF Viewer: Complete guide to building with react-pdf in 2025
    TL;DR

    react-pdf provides basic PDF rendering with custom UI development required. Nutrient offers a complete PDF solution with built-in UI, annotations, forms, and WebAssembly-powered performance. Compare implementation approaches based on your requirements.

    When building a React PDF viewer, you have several options: basic HTML elements, the open source react-pdf library, or Nutrient's React PDF library. Each approach offers different trade-offs in implementation complexity, feature coverage, and maintenance requirements.

    This comprehensive guide covers:

    1. Basic PDF embedding — HTML elements (<iframe>, <embed>, <object>) for simple display needs
    2. react-pdf implementation — Building a functional PDF viewer with the popular open source library
    3. Nutrient React PDF library — The professional solution with 30+ features, optimized performance, and complete UI

    Embedding PDFs in React apps using iframe, embed, and object

    If you don’t need advanced features like annotations or custom user interface (UI) controls, the easiest way to embed PDFs in your React app is by using native HTML tags such as <iframe>, <embed>, and <object>. These methods require no additional libraries and are quick to set up — ideal for basic PDF viewing.

    Using iframe

    The <iframe> tag is one of the most common ways to embed a PDF in a web application. It allows you to display a PDF document within a frame on your page.

    Example:

    function PDFViewer() {
    return (
    <div>
    <h2>Embedding PDF with iframe</h2>
    <iframe
    src="/document.pdf"
    width="100%"
    height="1000px"
    title="PDF Viewer"
    />
    </div>
    );
    }
    export default PDFViewer;

    Pros

    ✔ Easy to implement

    ✔ Works across all modern browsers

    ✔ Supports responsive sizing

    Cons

    ✘ No custom navigation or annotations

    ✘ Limited interactivity (e.g. no built-in text selection or zoom control)

    Alternatives: embed and object

    While <iframe> is the most common choice, <embed> and <object> offer similar capabilities with slight differences:

    • <embed> — Slightly more lightweight than <iframe>, but lacks fallback support for older browsers.
    • <object> — Offers better fallback handling (e.g. showing a download link if PDF rendering fails), and can embed other media types too, but is a bit more complex to implement.

    You can explore sample implementations for these tags here.

    Comparison of embedding methods

    MethodEase of useCustomizationFallback supportBrowser compatibility
    <iframe>⭐⭐⭐⭐✅ Excellent
    <embed>⭐⭐⭐⭐✅ Good
    <object>⭐⭐⭐⭐⭐✅ Excellent

    When to use these methods

    Use native HTML embedding methods when:

    • You just need to display PDFs — no navigation, search, or interactivity required.
    • You want a quick prototype without installing extra libraries.
    • You’re building a lightweight application that minimizes dependencies.

    However, these options fall short for projects needing advanced PDF controls, annotations, or a custom UI. For those, libraries like react-pdf or commercial SDKs like Nutrient offer much more flexibility and power.

    Limitations of embedding PDFs

    While these methods are simple, they come with limitations:

    • No custom UI — You can’t easily add custom navigation controls, annotations, or search functionality.
    • Limited interactivity — Users can’t interact with a PDF beyond basic viewing.
    • Performance issues — Large PDFs may load slowly or cause performance issues in the browser.

    For more advanced PDF rendering in React, you have two main options: the open source react-pdf library or Nutrient's React PDF library. The choice depends on your specific requirements for features, development time, and ongoing maintenance needs.

    React PDF implementation approaches: Technical comparison

    When selecting a React PDF solution, consider the technical trade-offs between open source and commercial options based on your application requirements.

    Open source react-pdf library

    react-pdf provides basic PDF rendering capabilities:

    • Downloads — ~950K weekly downloads on npm
    • Core functionality — Document rendering with Document and Page components
    • Implementation approach — Requires custom UI development for navigation and controls
    • Community support — Active developer community with community-driven maintenance

    Nutrient React PDF SDK

    Nutrient offers a comprehensive document processing platform:

    • Complete UI — Pre-built interface components with customization options
    • Feature set — 30+ capabilities including annotations, forms, signatures, and redaction
    • Performance — WebAssembly-powered rendering optimized for large documents
    • Support model — Commercial support with SLA guarantees
    • Development time — Reduced implementation time with pre-built components

    Requirements for building a React PDF viewer

    Before diving into react-pdf implementation, ensure you have:

    Implementation considerations: Evaluate whether custom development time with react-pdf aligns with project timelines, or if a comprehensive solution like Nutrient's React PDF library better fits your feature requirements and development resources.

    Building a React PDF viewer with react-pdf (open source approach)

    Start by creating a React.js project with vite(opens in a new tab):

    Terminal window
    npm create vite@latest react-pdf-demo -- --template react

    After the project is created, change the directory into the project folder:

    Terminal window
    cd react-pdf-demo

    Adding react-pdf

    1. Now, you can install the npm package for the react-pdf library from the terminal:

      Terminal window
      npm install react-pdf
    2. Place the file you want to render inside the public directory of the react-pdf-example project. You can use our demo document as an example; you just need to rename it to document.pdf.

    Displaying a PDF

    1. react-pdf comes with two components: Document and Page. Document is used to open a PDF and is mandatory. Within the document, you can mount pages, which are used to render the PDF page. To integrate this into your example project, open src/App.jsx and replace its contents with the following:

      import { useState } from "react";
      import { Document, Page } from "react-pdf";
      // Text layer for React-PDF.
      import "react-pdf/dist/Page/TextLayer.css";
      const App = () => {
      const [numPages, setNumPages] = useState(null);
      const [pageNumber, setPageNumber] = useState(1);
      const onDocumentLoadSuccess = ({ numPages }) => {
      setNumPages(numPages);
      };
      const goToPrevPage = () =>
      setPageNumber(pageNumber - 1 <= 1 ? 1 : pageNumber - 1);
      const goToNextPage = () =>
      setPageNumber(pageNumber + 1 >= numPages ? numPages : pageNumber + 1);
      return (
      <div>
      <nav>
      <button onClick={goToPrevPage}>Prev</button>
      <button onClick={goToNextPage}>Next</button>
      <p>
      Page {pageNumber} of {numPages}
      </p>
      </nav>
      <Document
      file="document.pdf" // Path to your PDF file.
      onLoadSuccess={onDocumentLoadSuccess}
      >
      <Page pageNumber={pageNumber} />
      </Document>
      </div>
      );
      };
      export default App;

      For react-pdf to work, a PDF.js worker needs to be provided. You can do this in a couple of ways. For most cases, importing the worker will work, as was done in the src/App.jsx file:

      import { pdfjs } from "react-pdf";
      pdfjs.GlobalWorkerOptions.workerSrc = new URL(
      "pdfjs-dist/build/pdf.worker.min.mjs",
      import.meta.url,
      ).toString();

      You can read more about how to configure a PDF.js worker in your project here(opens in a new tab).

    2. Now, start the application by running the following:

    Terminal window
    npm run dev

    One of the disadvantages of using react-pdf is that it doesn’t come with a UI. In this example, you’ve rendered two buttons to navigate between pages and showed the total number of pages.

    You can access the full code on GitHub(opens in a new tab).

    Technical limitations of react-pdf for complex applications

    While react-pdf works for basic PDF rendering, consider these technical constraints for feature-rich applications:

    • UI development required — No pre-built navigation, zoom controls, or toolbars
    • Text selection implementation — Text layer handling requires additional development work
    • Performance optimization — Large document handling needs custom memory management
    • Feature gaps — Annotations, forms, and signatures require separate implementations
    • Maintenance overhead — Browser compatibility and PDF.js updates need ongoing attention

    Development considerations: Factor in 2-4 months for building production-grade UI and features with react-pdf, versus using a complete SDK with pre-built components.

    Complete PDF solution: Nutrient React PDF library

    While the previous section demonstrated basic PDF viewing with react-pdf, many applications require additional document processing capabilities. Nutrient's React PDF library provides a comprehensive platform with minimal setup time.

    Nutrient provides comprehensive document processing features for React applications:

    Pre-built UI components — Responsive interface with configurable toolbars, navigation, zoom, and layout options

    Annotation system — 15+ annotation tools including highlights, shapes, and comments with programmatic API

    Document manipulation — Text editing, page management, redaction, and form processing capabilities

    Multi-format support — PDF, DOCX, XLSX, and image format rendering and processing

    Performance optimization — WebAssembly-based rendering for efficient large document handling

    Enterprise support — Commercial backing with technical support and regular updates

    Nutrient offers a complete document processing platform that reduces custom development time while providing enterprise-grade functionality.

    Creating a new React project

    Use vite(opens in a new tab) to scaffold out a simple React application:

    Terminal window
    npm create vite@latest nutrient-react-example -- --template react
    cd nutrient-react-example

    Install Nutrient Web SDK

    Next, install the @nutrient-sdk/viewer package:

    Terminal window
    npm i @nutrient-sdk/viewer

    Copying SDK assets to the public directory

    Nutrient Web SDK loads its WebAssembly and supporting files from a local path, so you need to copy them to the public folder. Start by installing the required copy plugin:

    Terminal window
    npm install -D rollup-plugin-copy

    Then, update your Vite config (vite.config.ts) to copy the SDK’s asset files during build:

    import { defineConfig } from "vite";
    import react from "@vitejs/plugin-react";
    import copy from "rollup-plugin-copy";
    export default defineConfig({
    plugins: [
    copy({
    targets: [
    {
    src: "node_modules/@nutrient-sdk/viewer/dist/nutrient-viewer-lib",
    dest: "public/",
    },
    ],
    hook: "buildStart",
    }),
    react(),
    ],
    });

    Displaying a PDF

    Now that everything is set up, you’ll render a PDF using the Nutrient SDK.

    Basic usage in App.tsx:

    import { useEffect, useRef } from "react";
    function App() {
    const containerRef = useRef(null);
    useEffect(() => {
    const container = containerRef.current;
    let cleanup = () => {};
    (async () => {
    const NutrientViewer = (await import("@nutrient-sdk/viewer")).default;
    // Unload any previous instance.
    NutrientViewer.unload(container);
    if (container && NutrientViewer) {
    NutrientViewer.load({
    container,
    document: "/example.pdf",
    baseUrl: `${window.location.protocol}//${
    window.location.host
    }/${import.meta.env.PUBLIC_URL ?? ""}`,
    });
    }
    cleanup = () => {
    NutrientViewer.unload(container);
    };
    })();
    return cleanup;
    }, []);
    return <div ref={containerRef} style={{ height: "100vh", width: "100vw" }} />;
    }
    export default App;

    You can also render a different file by changing the document path or making it dynamic.

    Once everything is configured, start your app:

    Terminal window
    npm run dev

    You’ll now see the Nutrient Web SDK UI rendering your PDF inside the browser!

    Note that because Nutrient is a commercial product, you’ll see a Nutrient Web SDK evaluation notice on the document. To get a license key, contact Sales.

    You can find the finished code on GitHub(opens in a new tab).

    Technical comparison: react-pdf vs Nutrient SDK

    Compare implementation approaches based on development requirements, feature coverage, and long-term maintenance considerations:

    Featurereact-pdf (Open Source)Nutrient React PDF Library ⭐
    Setup timeHours + custom UI development15 minutes with pre-built components
    UI componentsCustom development requiredComplete interface library
    Annotation toolsNot available15+ annotation types with API
    Form processingNot supportedComplete forms and e-signature support
    Text selectionBasic text layer handlingAdvanced selection with copy/paste
    Performance (large files)JavaScript-based renderingWebAssembly-optimized rendering
    File format supportPDF onlyPDF, DOCX, XLSX, images
    Mobile optimizationManual responsive implementationBuilt-in mobile interface
    Technical supportCommunity forumsCommercial support with SLA
    Development effort2-4 months for production featuresImmediate deployment

    Implementation decision: Consider development timeline, feature requirements, and maintenance resources when choosing between custom development and comprehensive SDK solutions. Evaluate options based on your specific needs.

    Accessibility considerations

    What each option provides

    • <iframe>, <embed>, <object> — Minimal a11y. Embedded PDFs are typically not exposed to screen readers; keyboard users struggle to reach or navigate the content. Little control over focus, roles, or labels.
    • react-pdf (open source) — You can add ARIA and basic keyboard navigation yourself, but the rendered text layer is often not announced properly without customization, and focus/semantics require manual work.
    • Nutrient Web SDK — Built-in support for accessible navigation and reading:
      • Screen reader compatible text layers and semantics
      • Full keyboard access (tab order, shortcuts, focus trapping/return)
      • High-contrast modes and color-accessible annotations
      • Accessible annotation tools and forms
      • Documentation and patterns aligned with WCAG and Section 508 out of the box

    Why it matters

    • Enterprises increasingly require WCAG conformance for internal and customer-facing apps.
    • Achieving parity with custom code in open-source viewers can be time-consuming and fragile.

    For accessibility compliance (e.g. WCAG or Section 508), Nutrient is the more robust solution.

    As React PDF viewer technology continues to evolve, several key trends are shaping the landscape. Nutrient leads the industry by supporting these modern requirements out of the box:

    Performance optimization

    • WebAssembly integration for faster rendering of large documents. Nutrient’s rendering engine leverages WebAssembly for high performance, especially with complex or large PDFs.
    • Lazy loading strategies for multi-page PDFs. Built-in virtualization and efficient page loading help optimize memory usage and performance in long-running applications.
    • Memory management improvements — Intelligent caching and disposal systems are designed to prevent memory leaks and ensure smooth operation.

    Mobile-First development

    • Responsive design requirements for seamless mobile PDF viewing. Nutrient’s UI automatically adapts to any screen size, providing a consistent experience across devices.
    • Touch gesture support for intuitive navigation on tablets and phones. Native touch gestures such as pinch-to-zoom, swipe navigation, and touch-friendly annotation tools are supported.

    AI and advanced features

    Security and Enterprise needs

    • Enhanced security protocols for sensitive document handling. Nutrient provides encryption, content security policies, and secure document transmission.
    • Digital signature verification built into viewer components. Support for electronic and digital signatures, including certificate-based verification.
    • Enterprise authentication and permissions — Role-based permissions and integration with enterprise authentication systems are supported.

    Unlike open source alternatives that require custom development for these features, Nutrient provides comprehensive support for all major 2025 React PDF viewer trends, ensuring your application stays current with minimal development effort.

    Conclusion: Selecting the right React PDF implementation

    This guide covered three approaches to building a React PDF viewer, from basic HTML embedding to the react-pdf library to Nutrient's comprehensive SDK. The optimal choice depends on your specific requirements for features, development resources, and timeline.

    Implementation decision framework:

    • Simple display needs? → Use HTML <iframe> embedding for basic PDF viewing
    • Custom UI requirements? → Consider react-pdf with 2-4 months development budget
    • Comprehensive document processing? → Evaluate Nutrient SDK for complete functionality

    Technical considerations for Nutrient adoption:

    • Accelerated development — Pre-built components reduce implementation time
    • User experience consistency — Professional interface patterns and interactions
    • Enterprise-grade reliability — Production-tested with commercial support
    • Complete feature coverage — Annotations, forms, signatures, and editing capabilities
    • Ongoing maintenance — Regular updates and technical support included

    Evaluate your application requirements and development resources when selecting a PDF solution. Compare implementation approaches or explore technical capabilities to determine the best fit for your project.

    Beyond React, Nutrient supports all major frameworks: Vue.js, Angular, vanilla JavaScript, and jQuery. View all framework options and find the perfect fit for your stack.

    FAQ

    What's the best React PDF library: react-pdf vs Nutrient?

    The choice depends on your requirements. react-pdf works well for basic PDF rendering with custom UI development, while Nutrient provides comprehensive document processing with pre-built components. Nutrient offers complete UI, 30+ features, WebAssembly performance, and commercial support — reducing development time compared to building custom solutions with react-pdf.

    How do I build a React PDF viewer with react-pdf?

    To create a React PDF viewer with react-pdf: 1) Install the library (npm install react-pdf), 2) Import Document and Page components, 3) Configure the PDF.js worker, and 4) Build your own UI controls. However, this approach requires significant development time compared to using Nutrient's ready-made solution.

    What are the main limitations of react-pdf for production apps?

    The main react-pdf limitations include:

    • No built-in UI (requires custom development)
    • Poor text selection experience
    • Performance issues with large files
    • No annotation or form-filling capabilities
    • Ongoing maintenance burden

    See the complete limitations comparison.

    Should I use react-pdf or Nutrient for my React PDF project?

    Consider your project requirements and development resources. react-pdf works well for prototypes and simple PDF viewing with custom UI development. Nutrient provides enterprise-grade PDF functionality with rapid setup, professional UI components, annotations, forms, signatures, and optimized performance. Evaluate development timeline and feature needs when making this decision.

    Can I migrate from react-pdf to Nutrient easily?

    Yes! Migrating from react-pdf to Nutrient is straightforward and provides immediate benefits. Nutrient's React integration replaces your custom react-pdf implementation with a single component that includes all the features you were building manually. Most teams complete the migration in a few hours.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer at Nutrient who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    FREE TRIAL Ready to get started?