Skip to main content

react-native-better-pdf

react-native-better-pdf, the native PDF viewer for React Native and Expo (PdfView, PdfDocument, PdfCache). Use when writing, reviewing or debugging code that shows or reads PDFs with react-native-better-pdf, when adding a PDF viewer to a React Native app, and when migrating an app from react-native-pdf.

معلومات المصدر

المستودع
gmi-software/better-skills
آخر نشاط في المصدر
١٣ أكتوبر ٢٠٢٦ في ١٤:٢٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣
التفرعات
٠

react-native-better-pdf: build and migrate PDF viewers

Guide a React Native or Expo app using PdfView, PdfDocument and PdfCache, including migration from react-native-pdf.

Prerequisites

The package uses React Native New Architecture and react-native-nitro-modules. Expo needs a development build; Expo Go cannot load the native viewer.

Limitations

Page indexes are zero-based in the API. Check the installed package version for exact signatures; the source Skill documents version 1.0.0.

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
8 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
react-native-better-pdf
description
react-native-better-pdf, the native PDF viewer for React Native and Expo (PdfView, PdfDocument, PdfCache). Use when writing, reviewing or debugging code that shows or reads PDFs with react-native-better-pdf, when adding a PDF viewer to a React Native app, and when migrating an app from react-native-pdf.
license
MIT
metadata
{"package":"react-native-better-pdf","version":"1.0.0","commit":"e93ad5366ae4fe2a7f5d0eedcb05c44fe06abeb7","verified":"2026-10-13","repository":"https://github.com/gmi-software/react-native-better-pdf","audience":"library users","tags":"react-native, pdf, pdf-viewer, pdfkit, pdfrenderer, nitro, expo, ios, android, react-native-pdf, migration"}
# react-native-better-pdf A Nitro View over the platform PDF engines: PDFKit on iOS, `PdfRenderer` on Android. JS sends configuration and commands; native code scrolls, zooms, renders, downloads and caches, and reports **settled** events (loaded, page changed, zoom ended, viewport stopped), never per-frame ones. Write code that configures the viewer and reacts to settled events; motion stays native. ## Ground truth: the installed package This skill is verified against 1.0.0; a newer installed version may add APIs it does not list (`version` in `node_modules/react-native-better-pdf/package.json`). For exact signatures, read the package itself: - `node_modules/react-native-better-pdf/src/PdfView.tsx`: every prop and ref method, with TSDoc. - `node_modules/react-native-better-pdf/src/index.ts`: every export; all types come from the package root. - `node_modules/react-native-better-pdf/README.md`: the full guide. List its sections with `grep -n '^## ' node_modules/react-native-better-pdf/README.md` and read the one you need. Before the package is installed (e.g. while planning a migration), the same files are at https://github.com/gmi-software/react-native-better-pdf. ## Rules 1. **Zero-based pages** everywhere: `onPageChange`, `onPageTap`, `initialPage`, `goToPage`, `renderPage`, outline items, overlays, viewports. Add 1 only in text shown to people. 2. **Initial props apply once per loaded document**: `initialPage`, `initialScale`, `initialViewport`. Later navigation goes through the ref: `goToPage(page, { animated })`, `zoomTo(scale)`, `goToViewport(viewport)`. Where the document opens comes from the initial props: ref calls before `onLoad` are not reliably applied. Out-of-range pages are clamped to the document. 3. **Scale is relative to the fitted page** (`fitPolicy`): `1` is fitted, `zoomTo(1)` resets, `minScale` / `maxScale` default to `1` / `4`. 4. **Sources compare by value.** An inline `source={{ uri }}` literal is fine: re-renders never reload. A changed password always reloads. Without a `cacheKey`, a changed `uri` or `headers` reloads; with one, only a changed key does (signed URLs, rotating tokens). The forms: `{ uri, headers? }` (`https://`, `http://`, `file://`, Android `content://`), `{ filePath }` (absolute path, no `file://`), and `require('./doc.pdf')` (Metro needs no config). Base64 data is written to a file first, then opened as a file. 5. **The app owns the loading UI.** Render an indicator until `onLoad` or `onError`. `onLoadProgress` reports bytes, `{ loadedBytes, totalBytes? }`, at most every 100 ms plus a final event before `onLoad`; `totalBytes` is `undefined` when the server sends no size. It fires only while a remote document downloads: local files, bundled assets and stored copies open without it. 6. **Match errors on `error.code`**, identical on both platforms: `invalid-source`, `file-not-found`, `network-error`, `http-error` (with `httpStatus`), `invalid-pdf`, `password-required`, `invalid-password`, `unsupported-pdf` (Android only: an encrypted file the device's renderer cannot open), `page-render-failed` (with `page`), `out-of-memory`. `message` is English that may change between versions: show people your own text per code, and log `code` with `message`. `PdfDocument.open` and `PdfCache.download` reject with `PdfOpenError` / `PdfDownloadError`, carrying the same `code`. 7. **URL links are reported, never opened.** Open them in `onLinkPress` after checking the scheme: a PDF is untrusted input. Links to other pages are followed natively. 8. **Taps:** `onPageTap` gives `{ page, x, y }` in PDF points from the page's top-left, after a ~300 ms wait for a possible double tap. `enableDoubleTapZoom={false}` delivers it at once. 9. **The app places the box.** The viewer adds no safe-area insets (keep it in a `SafeAreaView`, or use `contentInset` under translucent bars) and is transparent around the pages (set `style.backgroundColor`). `style.borderRadius` clips the document. 10. **Android gates some features.** Search, text selection, password-protected files and form filling need Android 15+, or Android 12–14 with SDK extension 13. Elsewhere search reports `isSupported: false`, protected files fail with `unsupported-pdf`, and `setFormFieldValues` rejects. Build the UI for these outcomes: hide search on `isSupported: false`, explain `unsupported-pdf`. 11. **Close what you open.** A `PdfDocument` holds its file until `close()`: call it in `finally`. `renderPage` writes files to the cache directory that the app owns: move them to keep them, delete them when done. 12. **New Architecture only; rebuild after installing.** Install with the peer `react-native-nitro-modules`, then rebuild the native app (`pod install` and a new build). Expo: a development build (`npx expo prebuild`, `npx expo run:ios` / `run:android`), no config plugin; Expo Go cannot load it. ## Minimal viewer ```tsx import { useState } from 'react'; import { ActivityIndicator, Linking, StyleSheet, Text, View } from 'react-native'; import { PdfView } from 'react-native-better-pdf'; export function Reader({ uri }: { uri: string }) { const [settledUri, setSettledUri] = useState<string>(); // the document that loaded or failed const isLoading = settledUri !== uri; const [page, setPage] = useState(0); const [pageCount, setPageCount] = useState(0); return ( <View style={{ flex: 1 }}> <PdfView key={uri} // events carry no source: a new viewer per document keeps a late event from the previous one apart style={{ flex: 1, backgroundColor: '#E4E4E7' }} source={{ uri }} onLoad={(event) => { setPageCount(event.pageCount); setSettledUri(uri); }} onError={(error) => { setSettledUri(uri); console.warn(error.code, error.message); }} onPageChange={({ page }) => setPage(page)} onLinkPress={({ url }) => { if (url.startsWith('https://')) Linking.openURL(url); }} /> {isLoading && <ActivityIndicator style={StyleSheet.absoluteFill} />} <Text>{pageCount > 0 ? `${page + 1} / ${pageCount}` : ''}</Text> </View> ); } ``` Type the ref with `useRef<PdfViewRef>(null)`; its async methods (`getOutline`, `getPageSizes`, `renderPage`, `print`, form methods) are for after `onLoad`. ## Where to go next | Task | Read | | --- | --- | | Replacing react-native-pdf in an app | [references/migrate-from-react-native-pdf.md](references/migrate-from-react-native-pdf.md): a step-by-step procedure, followed in order | | Remote documents: headers, tokens, signed URLs, offline reading, downloading ahead (`PdfCache`), base64 data | [references/sources-and-caching.md](references/sources-and-caching.md) | | Page jumps, a table of contents, restoring the reading position, horizontal / paged / right-to-left / single-page layouts, facing pages, translucent bars, dark pages | [references/navigation-and-layout.md](references/navigation-and-layout.md) | | Thumbnails, page images, covers and metadata for document lists (`PdfDocument`), page sizes, printing | [references/pages-and-documents.md](references/pages-and-documents.md) | | Search UI, text selection, forms (AcroForm), React views on pages (`PdfPageOverlay`: signatures, markers, pins) | [references/search-forms-overlays.md](references/search-forms-overlays.md) | | Install and build problems, Expo, Jest mocks, the Android capability matrix, common problems | [references/setup-and-troubleshooting.md](references/setup-and-troubleshooting.md) |
عرض على GitHub