EmbedPDF
React PDF Viewer

The React PDF viewer with the hard parts already built

Add one component and your users can read, search, highlight, fill in and sign PDFs right inside your React app. Want your own look? Build it with our React hooks instead. Free and open source.

4K+stars1M+downloadsApache-2.0 licensed
The EmbedPDF viewer running in a React app
App.tsx
import { PDFViewer } from '@embedpdf/viewer-react';

export function App() {
  return (
    <PDFViewer
      src="/report.pdf"
      style={{ height: '100vh' }}
    />
  );
}
Fits your React stack
  • React 18 and 19
  • Next.js and Vite
  • Every prop typed

Works with the React UI libraries you already use

  • Tailwind CSS
  • shadcn/ui
  • Material UI
  • Chakra UI
  • Ant Design
  • Radix UI
Find your fit

Two ways to build a React PDF viewer

The same PDF engine and the same features. Pick how much of the interface you want to own.

Best for shipping fast

Ready-made Viewer

A complete PDF viewer in one React component, ready in minutes.

  • One <PDFViewer /> component
  • Toolbar, panels and menus included
  • Your colors, buttons and components
Best for full control

Headless Components

React hooks and components for every feature, with no UI of their own.

  • Hooks for every feature
  • Your design system, your markup
  • Only what you import is bundled
Compare options

Find the right option for your React app

Both options use the same PDF engine and the same plugins. The difference is how much is done for you, and how much you want to decide yourself.

CapabilityReady-made viewerHeadless
Time to a working viewerMinutes: one componentLonger: you build the interface
InterfaceToolbar, panels, menus and dialogs includedNone: your components, your design
BrandingAccent color, light and dark, --epdf-* CSS variablesAll of it: the markup and CSS are yours
Your own componentsIn toolbars and panels, with <ToolbarItem>Everywhere: the whole UI is yours
React stateonReady gives you the viewer and its pluginsHooks like useSearchState(); pick a value to re-render only on it
Annotations, forms, searchAll included and switched onThe same plugins, added as you need them
BundleOne package with every feature; turn off what you don’t useEach feature is its own import
Next.js App RouterRender it from a server component, nothing to wrapMark your viewer component 'use client'
Best forMost apps, and shipping fastProducts where the viewer is part of your design
See the difference

Both options, running live

These are real viewers, running in your browser from the code next to them. Switch between them to see what each option gives you.

ReadyMadeViewer.tsx
'use client';

import { PDFViewer } from '@embedpdf/viewer-react';

export function ReadyMadeViewer() {
  return (
    <PDFViewer
      src="/embedpdf-documents-belong-on-the-web.pdf"
      theme={{ preference: 'light', accent: '#0876FD' }}
      style={{ height: '100%' }}
    />
  );
}
LiveOne component, and the toolbar, panels, search, annotations and forms come with it. Try them.
Grow with confidence

A clear path from simple to fully custom

Start with the ready-made viewer and change only what you need, when you need it. Every step runs on the same engine and the same plugins.
  1. 1

    Start with the ready-made viewer

    One component, every feature. Plenty of apps never need more.
  2. 2

    Make it yours

    Your color, your buttons, and your React components in the toolbar with <ToolbarItem>.
  3. 3

    Go headless when you need to

    Build the whole UI yourself with hooks. The plugins, their names and settings stay the same.
FAQ

React PDF viewer questions

Short answers to what React developers ask us most.

How is EmbedPDF different from react-pdf?

react-pdf is a good library for drawing PDF pages in React. It gives you a Document and a Page component on top of PDF.js, and everything around the pages is yours to build: the toolbar, zoom buttons, a search box, thumbnails, and any way to mark up the file. EmbedPDF gives you all of that ready to use, plus annotations, forms, signatures and redaction that are saved into the PDF itself. It runs on PDFium, the PDF engine inside Chrome, instead of PDF.js.

Does it work with the Next.js App Router?

Yes. <PDFViewer> is already a client component, so you can render it straight from a server component. There is no "use client" file to add, no dynamic import and no ssr: false. The server sends an empty box of the size you set, and the viewer starts in the browser. If you build your own UI with the headless hooks, mark that component "use client", like any component that uses hooks.

Can I start with the ready-made viewer and switch to headless later?

Yes, and you don’t have to switch all at once. Both run on the same engine and the same plugins, with the same names and settings. Many apps start with <PDFViewer>, add their own buttons and components to it, and only move to the headless hooks when the viewer has to look completely like their product.

Which React versions are supported?

React 18 and React 19. The package lists react >= 18 as its only peer dependency, so it works with Vite, Next.js and any other setup that runs React 18 or later.

Will Tailwind or my global CSS break the viewer?

No. The ready-made viewer draws inside a shadow DOM, so resets like Tailwind’s preflight can’t reach it. You style it on purpose instead: a theme prop for colors, and --epdf-* CSS variables for every color and corner. With the headless hooks there is nothing to protect: the markup is yours.

How do I control the viewer from my own code?

Use the onReady prop. It hands you the viewer once it is live, and every feature is a plugin you reach by name: viewer.get("search").search({ text: "total" }) runs a search, for example. The headless docs describe every plugin’s methods.

Do my PDFs get uploaded anywhere?

No. The PDF engine runs as WebAssembly in a Web Worker inside the user’s browser. Files are opened, edited and saved on the device. The engine files are part of your own build, so nothing is fetched from a third party unless you set that up.

Is it free for commercial projects?

Yes. EmbedPDF is open source under the Apache-2.0 license. You can use it in commercial and closed-source products without paying, and without having to open source your own code.

Ready when you are

Ship PDFs in your React app this afternoon

Install one package, render one component, and your users have a full PDF viewer. Open source under Apache-2.0, free for commercial use.

Terminal
npm install @embedpdf/viewer-react@next