npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ngx-pdfium-viewer

v0.2.0

Published

Angular PDF viewer built on PDFium (WASM): pinch-zoom, search, links, form fields and thumbnails, tuned for mobile WebViews.

Downloads

44

Readme

ngx-pdfium-viewer

Angular PDF viewer built on PDFium compiled to WebAssembly via @embedpdf/pdfium. Renders directly to canvas — no pdf.js, no iframe.

  • Pinch-zoom with focal-point precision, bounded two-finger pan, fit-width floor
  • Lazy page rendering with scroll-aware batching for long documents
  • Text search with highlight overlays
  • Clickable links (URI, internal goto, launch)
  • AcroForm text fields: view, edit, save the filled PDF
  • Thumbnail sidebar, print, download
  • Tuned for Ionic/Capacitor WebViews (iOS canvas-memory limits, Android touch)

Requires Angular 20+.

Install

npm install ngx-pdfium-viewer @embedpdf/pdfium

Ship the WASM binary

PDFium runs from a .wasm file that your app must serve. Add this to the assets array of your build target in angular.json (both build and test if present):

{
  "glob": "pdfium.wasm",
  "input": "node_modules/@embedpdf/pdfium/dist",
  "output": "assets/pdfium"
}

The viewer fetches assets/pdfium/pdfium.wasm by default. To serve it from somewhere else (a CDN, a different path), provide the URL:

import { providePdfiumWasmUrl } from 'ngx-pdfium-viewer';

bootstrapApplication(AppComponent, {
  providers: [providePdfiumWasmUrl('https://cdn.example.com/pdfium.wasm')],
});

Two ways to use it

| import | what you get | extra peers | |---|---|---| | ngx-pdfium-viewer | PdfiumComponent — the viewer surface, no chrome | none | | ngx-pdfium-viewer/ionic | PdfiumShellComponent — a complete screen: nav bar, tool bar, find bar, page HUD, loading overlay | @ionic/angular >=9, ionicons, @angular/forms |

Reach for the shell if you want a working viewer out of the box, and for PdfiumComponent if you are building your own chrome.

The ready-made screen

npm install ngx-pdfium-viewer @embedpdf/pdfium @ionic/angular ionicons
import { Component } from '@angular/core';
import { PdfiumShellComponent } from 'ngx-pdfium-viewer/ionic';

@Component({
  selector: 'app-reader',
  imports: [PdfiumShellComponent],
  template: `
    <ngx-pdfium-shell
      src="assets/manual.pdf"
      documentTitle="Manual"
      backHref="/home"
      (linkClicked)="onLink($event)"
    ></ngx-pdfium-shell>
  `,
})
export class ReaderComponent {
  onLink(url: string) { /* … */ }
}

The shell needs Ionic 9 or newer: it imports Ionic's standalone components from the @ionic/angular root, which on Ionic 8 is still the NgModule build.

Shell inputs

| input | type | notes | |---|---|---| | src | string (required) | URL of the PDF to load | | documentTitle | string | Shown in the nav bar and on the loading overlay | | backHref | string \| null | Back-button target; leave unset to hide the button | | paddingTop / paddingBottom | string | Insets inside the scroll area; defaults clear the header and the floating page HUD | | openLinks | boolean | Whether to window.open a clicked link. Set false when you handle linkClicked yourself |

Shell outputs

| output | payload | |---|---| | linkClicked | string URI — always emitted, whatever openLinks is set to | | pageCountReady | number | | currentPageChanged | number (0-based) |

To open links with Capacitor's in-app browser instead of a new tab:

<ngx-pdfium-shell src="assets/manual.pdf" [openLinks]="false" (linkClicked)="open($event)" />

The entry point also exports each bar (PdfNavBarComponent, PdfActionBarComponent, PdfFindBarComponent, PdfPageHudComponent, PdfLoadingOverlayComponent) and the controllers behind them, for hosts that want to compose a different layout. Each bar resolves its controllers through DI, so it must sit inside a component that provides them — see PdfiumShellComponent for the arrangement.

Use the viewer directly

PdfiumComponent is standalone.

import { Component } from '@angular/core';
import { PdfiumComponent } from 'ngx-pdfium-viewer';

@Component({
  selector: 'app-reader',
  imports: [PdfiumComponent],
  template: `
    <ngx-pdfium-viewer
      [src]="'assets/manual.pdf'"
      [searchTerm]="term"
      (onPageCountReady)="pages = $event"
      (onCurrentPageChanged)="current = $event"
      (onLinkClicked)="open($event)"
    ></ngx-pdfium-viewer>
  `,
})
export class ReaderComponent {
  term = '';
  pages = 0;
  current = 0;
  open(url: string) { window.open(url, '_blank'); }
}

In an NgModule-based app, add PdfiumComponent to the module's imports (not declarations).

Inputs

| input | type | notes | |---|---|---| | src | string (model) | URL of the PDF to load | | searchTerm | string | Highlights every match; empty clears | | searchIndex | number (model) | Active match, 0-based | | paddingTop / paddingBottom | string | CSS length applied inside the scroll area — for toolbars, safe-area insets |

Outputs

| output | payload | |---|---| | onProgress | number 0..1 while loading | | onPageCountReady | number | | onCurrentPageChanged | number (0-based) | | onInitialPagesRendered | — first batch on screen | | onSearchInfoChanged | SearchInfo { searchTerm, index, total } | | onLinkClicked | string URI | | onFormFieldsReady | number fields found | | onThumbnailsChanged | boolean sidebar open | | onClick | PointerEvent tap on the page (not on a link or field) |

Methods (via viewChild)

zoomIn(), zoomOut(), onZoomChange(scale), applyFitWidth(), scrollToPage(i), goToNextPage(), goToPreviousPage(), navigateToMatch(i), highlightWord(word), clearHighlights(), toggleThumbnails(), setFormFieldValuesInPdf(values), getFilledPdfBytes(), savePdf(), printPdf(), extractLinks().

Memory on iOS

WebKit caps canvas memory at roughly 256 MB. The viewer caps device pixel ratio at 2, allocates page bitmaps lazily, and releases them on destroy. If you open many large documents in one session, destroy the component between them rather than swapping src.

Build and publish

The library is built from source, then published from dist/:

npm login
ng build ngx-pdfium-viewer
cd dist/ngx-pdfium-viewer && npm publish

publishConfig.access is public. Unscoped packages are public by default, so this is belt-and-braces — it keeps the publish public if the package is ever scoped.