---
title: "How to build a React.js PDF viewer with Nutrient"
canonical_url: "https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer/"
md_url: "https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer.md"
last_updated: "2026-08-11T08:57:05.224Z"
description: "A step-by-step guide to how to build a React.js PDF viewer with Nutrient."
---

**TL;DR**

This step-by-step guide shows you how to build a [PDF viewer](https://www.nutrient.io/sdk/solutions/viewing/) in React using Nutrient Web SDK. You’ll set up a React app using Vite, install the SDK, and display a PDF with full viewer controls.

- **Modern tech stack** — Vite + React + WebAssembly-based viewer

- **Supports PDF, DOCX, and image formats** — View and annotate files client-side

- **Prebuilt UI** — Includes 30+ features like comments, highlights, signatures, and redaction

- **Secure and scalable** — Built for enterprise workflows with CSP, encryption, and compliance support

- **Fast to integrate** — Load a document in fewer than 10 lines of code

Perfect for apps that need a reliable, production-grade PDF viewer with advanced capabilities.

The video tutorial above uses create-react-app. We now recommend using Vite, as detailed below.

## What is a React PDF viewer?

A React PDF viewer lets you render and view PDF documents in a web browser without the need to download it to your hard drive or use an external application like a PDF reader.

## Nutrient React PDF viewer

We offer a commercial [React.js PDF viewer library](https://www.nutrient.io/guides/web/viewer.md) that can easily be integrated into your web application. It comes with 30+ features that let you view, annotate, edit, and sign documents directly in your browser. Out of the box, it has a polished and flexible UI that you can extend or simplify based on your unique use case.

- A prebuilt and polished UI for an improved user experience

- 15+ prebuilt annotation tools to enable document collaboration

- Support for more file types with client-side [PDF](https://www.nutrient.io/guides/web.md), [MS Office](https://www.nutrient.io/guides/web/viewer.md), and [image](https://www.nutrient.io/guides/web/viewer/images.md) viewing

- Dedicated support from engineers to speed up integration

Looking for other React PDF solutions? Check out our comprehensive guide to [React PDF libraries and alternatives](https://www.nutrient.io/blog/top-react-pdf-viewers/), or explore related framework guides for [Angular](https://www.nutrient.io/guides/web.md) and [Vue.js](https://www.nutrient.io/guides/web.md).

## Example of our React.js PDF viewer

To demo our [React.js PDF viewer](https://www.nutrient.io/demo/), upload a PDF, JPG, PNG, or TIFF file by selecting **Open Document**. Once your document is displayed in the viewer, try drawing freehand, adding a note, or applying a crop or an eSignature.

## Requirements to get started

To get started, you'll need:

- The [latest version of Node.js](https://nodejs.org/en/).

- A package manager compatible with npm. This guide contains usage examples for [Yarn](https://yarnpkg.com/) and the [npm](https://docs.npmjs.com/cli/v7/commands/npm) client (installed with Node.js by default).

## Setting up a new React project with Vite

Use [`vite`](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) to scaffold out a simple React application:

```bash

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

```

### Install Nutrient Web SDK

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

```bash

npm install @nutrient-sdk/viewer

# or

yarn add @nutrient-sdk/viewer

# or

pnpm install @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:

```bash

npm install -D rollup-plugin-copy

```

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

```ts

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`:

```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:

```bash

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](https://www.nutrient.io/contact-sales/?=sdk).

## Adding even more capabilities

Once you’ve deployed your viewer, you can start customizing it to meet your specific requirements or easily add more capabilities. To help you get started, here are some of our most popular React.js guides:

- [Adding annotations](https://www.nutrient.io/guides/web/annotations.md)

- [Editing documents](https://www.nutrient.io/guides/web/editor.md)

- [Filling PDF forms](https://www.nutrient.io/guides/web/forms.md)

- [Adding signatures to documents](https://www.nutrient.io/guides/web/signatures.md)

- [Real-time collaboration](https://www.nutrient.io/guides/web/instant-synchronization.md)

- [Redaction](https://www.nutrient.io/guides/web/redaction.md)

- [UI customization](https://www.nutrient.io/guides/web/user-interface.md)

## Conclusion

You should now have our React PDF viewer up and running in your web application. If you hit any snags, don’t hesitate to reach out to our [Support team](https://www.nutrient.io/support/request/) for help.

You can also deploy our vanilla [JavaScript PDF viewer](https://www.nutrient.io/blog/how-to-build-a-javascript-pdf-viewer.md) or use one of our many web framework deployment options like [Vue.js](https://www.nutrient.io/blog/how-to-build-a-vuejs-pdf-viewer.md), [Angular](https://www.nutrient.io/blog/how-to-build-an-angular-pdf-viewer/), and [jQuery](https://www.nutrient.io/blog/how-to-build-a-jquery-pdf-viewer/). To see a list of all web frameworks, start your [free trial](https://www.nutrient.io/sdk/web/getting-started.md). Or, [launch our demo](https://www.nutrient.io/demo/) to see our viewer in action.

Prefer an open source approach in React? See our guides on the [react-pdf library](https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md), [rendering PDFs with PDF.js](https://www.nutrient.io/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md), or building a [multiformat React file viewer](https://www.nutrient.io/blog/how-to-build-a-reactjs-file-viewer.md).
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [or](/blog/merge-pdfs.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Building WCAG 2.2, Section 508, and PDF/UA-compliant PDFs with an SDK](/blog/pdf-accessibility.md)
- [Pdf Data Extraction Developer Guide](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

