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

@meedwire/react-native-pdf-api

v0.1.1

Published

Native PDF rendering, search and text extraction API for React Native (iOS & Android), built on TurboModules + Fabric.

Readme

@meedwire/react-native-pdf-api

npm version license New Architecture

Native PDF rendering, text extraction and search for React Native (iOS & Android), built on TurboModules + Fabric. Ships a native PdfView component for displaying documents plus an imperative API for metadata, page rendering, thumbnails, text extraction and search.

  • 📄 Native viewer with vertical scroll, pinch‑zoom and initial page
  • 🔎 Text search with page coordinates to highlight / focus results
  • 🖼️ Render any page to a PNG/JPEG file (full size or thumbnail)
  • 📝 Extract text per page or for the whole document
  • 🌐 Built‑in native download + cache for remote (http/https) PDFs — no extra file‑system dependency required
  • ⚡ New Architecture only (TurboModule + Fabric), iOS in Swift, Android in Kotlin — no hand‑written C++

Platform support

| Feature | iOS | Android | Web | | ----------------- | -------------------- | ------------------------------- | ------------------- | | Viewer (PdfView)| ✅ PDFKit | ✅ PdfRenderer | ⛔ falls back to View | | Render page | ✅ | ✅ | ⛔ | | Extract text | ✅ | ✅ Android 15 / API 35+ | returns null | | Search text | ✅ | ✅ Android 15 / API 35+ | returns [] | | Metadata | ✅ | Page count only | ⛔ | | Password‑protected| ⛔ (planned) | ⛔ (planned) | ⛔ |

Use document.capabilities (from openDocumentAsync()) to check, at runtime, whether text/search are available on the current platform/OS.

Requirements

  • React Native 0.79+ with the New Architecture enabled (newArchEnabled=true). This package does not support the legacy architecture (Paper).
  • iOS 15+ with PDFKit. Android minSdkVersion 24 (text/search require API 35+).

Installation

yarn add @meedwire/react-native-pdf-api
# or
npm install @meedwire/react-native-pdf-api

iOS:

cd ios && pod install

Then rebuild the native app (yarn ios / yarn android). This package contains native code, so it does not work in Expo Go — use a development build (npx expo prebuild + npx expo run:ios|android).

Quick start — PdfView

import { useRef } from 'react';
import { Button, StyleSheet, View } from 'react-native';
import { PdfView, type IPdfViewRef } from '@meedwire/react-native-pdf-api';

export function PdfScreen() {
  const pdfRef = useRef<IPdfViewRef>(null);

  return (
    <View style={styles.container}>
      <PdfView
        ref={pdfRef}
        source="https://example.com/document.pdf"
        style={styles.pdf}
        initialPage={0}
        maxZoom={5}
        pageSpacing={16}
        backgroundColor="#f4f4f1"
        onLoad={({ nativeEvent }) => console.log('pages', nativeEvent.pageCount)}
        onPageChange={({ nativeEvent }) => console.log('page', nativeEvent.currentPage)}
        onError={({ nativeEvent }) => console.warn(nativeEvent.code, nativeEvent.message)}
      />
      <Button
        title="Find"
        onPress={() => pdfRef.current?.searchTextAsync('contract', { focus: true })}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  pdf: { flex: 1 },
});

currentPage, initialPage, pageIndex and resultIndex are zero‑based.

Sources

type TypePdfSource =
  | string
  | { uri: string; headers?: Record<string, string>; cacheKey?: string; fileName?: string };

http/https sources are downloaded to the native cache before rendering; headers are sent with that request. Local file://, absolute paths and (on Android) content:// URIs are passed straight through.

Imperative API

import { openDocumentAsync, clearPdfCacheAsync } from '@meedwire/react-native-pdf-api';

const document = await openDocumentAsync({
  uri: 'https://example.com/document.pdf',
  headers: { Authorization: `Bearer ${token}` },
  cacheKey: 'document-v1.pdf',
});

try {
  const metadata = await document.getMetadataAsync();
  const page0 = await document.getPageInfoAsync(0);
  const rendered = await document.renderPageAsync(0, { format: 'png', width: 1200 });
  const thumb = await document.getThumbnailAsync(0);
  const text = await document.getTextAsync();
  const matches = await document.searchTextAsync('client', { maxResults: 10 });
} finally {
  await document.closeAsync();
}

await clearPdfCacheAsync();

API reference

PdfView props

| Prop | Type | Default | Description | | --------------------- | ---------------- | ----------- | --------------------------------------------- | | source | TypePdfSource | required | Local or remote PDF. | | style | ViewStyle | – | Give it real dimensions (e.g. flex: 1). | | backgroundColor | string | #f4f4f1 | Viewer background. | | initialPage | number | 0 | Zero‑based initial page. | | pageSpacing | number | 16 | Spacing between pages. | | maxZoom | number | 5 | Maximum zoom factor. | | maxPageResolution | number | 2048 | Android: largest rendered bitmap side. | | singlePage | boolean | false | Render only the initial page. | | onLoad | (e) => void | – | { documentId, pageCount, sourceUri, capabilities } | | onPageChange | (e) => void | – | { currentPage, pageCount } | | onError | (e) => void | – | { code, message } |

Handlers can be inline arrow functions — the component keeps the latest callbacks in refs, so passing new identities each render does not reload the document. onPageChange fires when the current page changes during scroll.

PdfView ref (IPdfViewRef)

  • openDocumentAsync()IPdfDocument
  • getTextAsync(pageIndex?)string | null
  • searchTextAsync(query, options?)IPdfSearchResult[] (also highlights/focuses)
  • clearSearchAsync()
  • closeDocumentAsync()

IPdfDocument

documentId, pageCount, sourceUri, capabilities, plus getMetadataAsync(), getPageInfoAsync(pageIndex), renderPageAsync(pageIndex, options?), getThumbnailAsync(pageIndex, options?), getTextAsync(pageIndex?), searchTextAsync(query, options?), closeAsync().

Render options

type IPdfRenderOptions = {
  format?: 'png' | 'jpeg'; // default png
  quality?: number;        // 0..1, default 0.9
  width?: number;          // keeps aspect ratio if only one is set
  height?: number;
  scale?: number;          // used when width/height absent
  backgroundColor?: string;
  maxPixels?: number;      // default 16_777_216, else ERR_PDF_RENDER_TOO_LARGE
};

Error codes (onError / rejected promises)

ERR_PDF_SOURCE, ERR_PDF_OPEN, ERR_PDF_LOCKED, ERR_PDF_PAGE_OUT_OF_BOUNDS, ERR_PDF_PAGE, ERR_PDF_DOCUMENT_NOT_FOUND, ERR_PDF_RENDER_TOO_LARGE, ERR_PDF_RENDER, ERR_PDF_TEXT_UNSUPPORTED, ERR_PDF_SEARCH_UNSUPPORTED.

Screenshots

The example app (example/) demonstrates the viewer, search highlight/focus and page navigation. To capture screenshots, run it on a simulator/emulator and save the images under docs/screenshots/ — see the capture guide.

# iOS
cd example/ios && pod install && cd -
npx react-native run-ios --simulator "iPhone 16"

# Android (with an emulator running)
npx react-native run-android

Contributing

This is a create-react-native-library project.

yarn            # install
yarn typecheck  # TypeScript
yarn lint       # ESLint + Prettier
yarn test       # Jest
yarn prepare    # build with react-native-builder-bob

The example app under example/ is the development harness. After changing native code, rebuild it (pod install for iOS, a fresh Gradle build for Android).

License

MIT © Meedwire