Pre-Purchase Insights: Everything you need to know before you buy.

A Starter's Guide to JavaScript PDF Viewers

By Apryse | 2023 Feb 15

Sanity Image
Read time

4 min

This guide will help you choose and implement the right JavaScript PDF viewer to meet your needs. Learn about and find resources for:

  1. Two very popular open-source methods to embed a PDF viewer in a web app or web page — PDF.js and React PDF.
  2. A commercial JavaScript PDF SDK, Apryse WebViewer, for projects with more complex needs, such as more features or file format support. Includes samples to get started and test its capabilities.

Comparing Open-Source Javascript PDF Viewers

Copied to clipboard

You can use some basic HTML and CSS methods to open PDF from a website or web page.

In cases, however, you'll want more control over how documents display than the browser's built-in viewer can provide. And you may also want to restrict users from downloading PDFs out of your application.

That's where embedding a PDF viewer comes in. You can find open-source libraries that will let you embed a PDF viewer in a web app or web page. These will give you more control over how your documents appear. And depending on your choice, you will find more or fewer features to enrich the reading experience.

Perhaps the two most popular JS libraries are PDF.js and React PDF. Both let you parse, render and display PDFs directly without a download but come with different levels of viewer functionality, with implications for projects. So let's take a closer look.

React PDF

502K weekly downloads on npm


  • Ready-to-go React components to display PDFs as images
  • Updated regularly


  • Must build your own reader UI
  • Uses PDF.js “under the hood”

Based on the popular JavaScript library of the same name, React PDF is a widely used way to render PDF files in both a browser and on a server. It is relatively easy to install and provides ready-to-go components such as Document or Page. It also still receives regular updates to keep it current.

That said, React PDF’s creator, Wojciech Maj, writes that React PDF is not meant to be a “fully fledged PDF reader.” Instead, it was created to be “an easy way to display PDFs so that you can build some UI around it.” This means React PDF does not come with an out-of-box UI. Instead, it requires you to build one — an option that may or may not be attractive.

React PDF also leverages PDF.js under its hood, which exposes it to a number of issues that cannot be solved by the React PDF contributor community. For example, selecting text can be difficult due to the PDF.js dependency. Other issues, such as incorrect text layers, can also occur, creating challenges for any search or highlight feature built on top React PDF.

With some customization and time, however, React PDF may be the basic PDF display method you’re looking for. Documentation is available through both npm and GitHub.


1.5 million weekly downloads on npm (pre-built version)


  • Out-of-box reader UI
  • Built-in zoom functionality
  • Multiple view and search options


  • Text selection and text search are less reliable
  • Difficulties with “graphics-heavy” or complex PDFs
  • Limited browser support outside Chrome, Firefox, and Edge
  • A “PDF reader only

The framework behind the React PDF library, PDF.js is likely the most popular open-source PDF viewer method. Like React PDF, it is free and straightforward to get started. However, it differentiates by providing an out-of-box UI from Mozilla, in addition to the ability to create your own. This out-of-box UI comes with features such as a built-in search, multiple view modes, and the ability to zoom in as much as 1,000 percent.

While these are advances over React PDF, there are also some significant drawbacks, especially when compared to most desktop and some mobile PDF viewers. The search feature, for example, will not return results that break a line, which may result in it missing important information. Likewise, the zoom feature, while adequate, falls short when trying to view particularly large and detailed images, such as a complex engineering drawing. This can potentially limit its usage, especially since PDF.js can sometimes struggle with complex or graphics-heavy PDFs, according to one benchmark on hacks.mozilla.

PDF.js faces a number of technical issues also. These include reduced image quality at higher zoom levels, limited support for older browsers, and text selection accuracy issues. As of this writing, there are 341 issues open on GitHub, an improvement from 2019, when PDF.js had over 600 open issues.

Depending on your needs, PDF.js may provide you with enough basic functionality to be useful. Documentation is available on the project's website.

Using Apryse to Build a Javascript PDF Viewer

Copied to clipboard

Open-source JavaScript PDF libraries are great for some projects. However, those looking for a wider array of editor and annotation features and a smoother UX will want to consider a JavaScript PDF SDK, such as Apryse Webviewer.

Apryse Javascript WebViewer Features

Apryse WebViewer is a JavaScript PDF & Document SDK that lets you add advanced document processing as part of any web application. It includes a deep feature set to let users create PDFs, add annotations and collaborate on documents, insert bookmarks and digital signatures, and more. The rendering performance and reliability are best-in-class.

Since most of WebViewer’s capabilities run client-side in the browser, it scales up or down cost-effectively with your application, and it streamlines secure integration of features.

Apryse WebViewer Features

  • Reliable, professional viewer performance, even with large and complex PDFs
  • Consistent across modern browsers, including mobile versions of Chrome, Firefox, and Edge
  • Displays MS Office files (xlsx, pptx, docx) and images dynamically, without a conversion server or MS Office software dependency
  • Performs document generation and manipulations such as redaction, page organization, watermarking, PDF content editing, and so on — no server required
  • Complete annotations, form building, form filling, and e-signature capabilities
  • Rich customization options via the APIs or the UI on GitHub to fork
  • All JavaScript frameworks supported (React, Angular, Vue.js, and so on)
  • Additional formats — audio, video, CAD, and websites — in the same JS SDK framework

Interested in our comprehensive buyer's guide for WebViewer? Check it out here.


  • Heaviest option
  • Commercially licensed — you’ll have to contact Sales for use in a production environment, though the trial does not require a license key to get started.

How to Get Started with Apryse WebViewer

Installing the Apryse JS WebViewer can be done via npm. If you’ve already installed npm, simply follow these instructions:

Note: Since WebViewer requires static resources to be served (which cannot be bundled), there is an extra step required which involves manually copying these static files into your dist directory.

Install via NPM

Run the following command in your project:

npm i @pdftron/webviewer

This will install the main JS entry point, as well as download some static assets required for WebViewer to run.

Copy static assets

Next, we must copy the static assets required for WebViewer to run into a public location that will be served via HTTP/HTTPS (usually a dist or build folder). The static files are located in node_modules/@pdftron/webviewer/public.

Below are a few ways you could automate this process:

1. NPM script

You could add a script to your package.json that moves the static files for you after your build completes. This will copy all required files into the dist/public folder after your build is complete.

  "scripts": { 
    "move-static": "cp -a ./node_modules/@pdftron/webviewer/public/. ./dist/public/webviewer", 
    "build": "mybuildscript && npm run move-static" 

2. WebPack

If you're using webpack to bundle your project, you can use copy-webpack-plugin to copy files for you automatically.

Install the package:

npm install copy-webpack-plugin --save-dev

Then add the following to your webpack config:

module.exports = { 


  plugins: [ 
    new CopyPlugin([{ 
        from: './node_modules/@pdftron/webviewer/public', 
        to: './dist/public/webviewer'

3. Parcel

If you are using parcel to bundle your project, you can use parcel-plugin-static-files-copy to copy your files.

Install the package:

npmi parcel-plugin-static-files-copy --save-dev

Then add the following to your package.json

  "staticFiles": { 
    "staticPath": [ 
        "staticPath": "node_modules/@pdftron/webviewer/public", 
        "staticOutDir": "public/webviewer" 
    "watcherGlob": "**" 

4. Other

If you're using a different package manager, look for a plugin that copies static files at build time.


When using WebViewer in your code, you will have to tell it where you copied these static files using the path parameter.

For example, if you copied the static files into dist/public/webviewer, your code would look something like this:


  path: '/public/webviewer', 

}, document.getElementById('viewer')) 
  .then(instance => { 
    const { UI, Core } = instance;
    const { documentViewer, annotationManager, Tools, Annotations } = Core; 
    // call methods from UI, Core, documentViewer and annotationManager as needed 
    documentViewer.addEventListener('documentLoaded', () => { 
      // call methods relating to the loaded document 



To learn more, check out our tutorial on using WebViewer’s standard API, check out samples on viewing different documents using Javascript, or read through our many other guides.


Copied to clipboard

While most modern browsers, as well as many iOS and Android apps, already employ their own built-in Javascript PDF viewers, embedding your own gives you a much greater degree of control over what users can see and do with your PDFs. You can turn to popular open-source viewer options, such as PDF.js and React PDF, for basic viewer functionality. However, Apryse WebViewer offers a far greater range of both flexibility and features.

Learn more about Apryse WebViewer or play around with our free demo.

Sanity Image


Share this post