Building a custom PDF viewer in React with your own controls
Most dev teams rely on 3rd-party libraries when implementing PDF viewers in React applications. While this is a great strategy for teams that need to ship features fast, building a truly lightweight and custom PDF viewer with features like responsive viewports and toolbars for zooming and pagination might require a more hands-on approach.
Faced with the bloat of large PDF libraries, their limited customization options, and user interfaces that may clash with the look and feel of your application, the temptation to build your own PDF viewer from scratch is understandable. A DIY PDF viewer will give you complete control over its customization but it also requires a significant time investment that might be better spent on other development tasks.
Fortunately, you don’t have to choose between a restrictive library and rolling your own PDF viewer from scratch. You’re better off using a JavaScript library such as react-pdf, which offers the best of both worlds by providing a highly customizable PDF viewer for any React application.
This post shows React developers how to create a fully custom React PDF viewer with custom controls such as:
viewing remote and locally saved PDFs
a customized UI
zoom in/out
pagination
Create a new React App
As a first step, create a new React application by opening a terminal and running the following command. It should create a react-pdf-viewer folder that contains scaffolding for developing a React application.
Next, navigate to the react-pdf-viewer folder and open it in your code editor or IDE.
Install dependencies
In the root directory of the react-pdf-viewer project, run the following terminal command to install react-pdf
and material icons
. Material icons will serve as intuitive labels for custom controls such as zoom and pagination buttons in the PDF viewer’s toolbar.
Define the Application’s State
Users need to be able to navigate to other pages, zoom, see what page they’re on, and so forth when viewing a PDF document. Let’s define the initial state and how to manage changes to documents opened in the viewer by creating an src/state.js file with the following as its contents:
Create a PDFViewer Component
Create a PDFViewer.jsx file in the src folder of the project and copy the following code into it.

Add Custom Controls to the PDF Viewer
Although the above PDFViewer
component is ready for use, it is currently missing the bells and whistles of most production-ready PDF viewers. Let's rectify that by creating a custom Toolbar
and a ControlButton
component to render the PDF viewer’s controls.
Create a Toolbar.jsx file in the src folder of the project and add the following components to it.
Passing a PDF File to the PDF Viewer
A PDF file is passed to react-pdf
's Document
component in one of two ways. It takes an object with a:
url
field set to the target PDF file’s URL.data
field set to aUint8Array
.
Render a PDF from a URL
This method is ideal for situations where you need to render a PDF document located on the server or a remote file hosting service such as an S3 bucket.
For example, to show users a PDF document when they click a button, replace the contents of the src/App.jsx file with the following:
Open a terminal at the root of the react-pdf-viewer folder and run npm run dev
. Then visit the URL displayed in the terminal.
You should be able to click the View PDF button to view and navigate the contents of the http://localhost:3001/dummy.pdf
file assuming you already have an HTTP server running on port 3001 of your computer that serves a dummy.pdf file.
The toolbar and dummy PDF file should (for now) appear similar to the following:

Render PDFs from the User's Computer
To allow users to view PDF documents stored locally on their devices, you can use a form with a file input element. To see this in action, create an src/PdfForm.jsx file and copy the following code into it:
If we replace the contents of the src/App.jsx file with the following, we should be able open and view locally saved PDF documents.
Now that the PDF viewer works, you can apply your application’s theme to the page to stay on brand. However, since this post focuses on demonstrating how to customize the PDF viewer’s interface, the following steps should suffice:
Delete or comment out the line containing
import './index.css'
in thesrc/main.jsx
file.Replace the contents of the src/App.css file with the following:
Now, reload the page. The viewer and toolbar should look similar to the following when you open a PDF file.

Using the react-pdf
library to build a custom PDF viewer provides a solid foundation for creating a lightweight, tailored document viewing experience. This is largely because the library abstracts the complexity of rendering PDFs while still allowing developers to customize the document’s interface and controls.
This post has demonstrated how to render both remote and locally stored PDFs, as well as how to implement essential custom controls such as zoom in/out functionality and pagination. However, the possibilities for customization extend far beyond these basics when leveraging a lightweight and flexible library like react-pdf.
If this was just the beginning of your PDF build and you want to achieve more robust capabilities, check out Joyfill — a PDF form filler SDK that you can embed into your web or mobile app.