PDF SDK for React Native (iOS & Android)
Papyrus mobile uses React Native UI plus a native engine bridge for PDF rendering on iOS and Android.
What it is: a React Native PDF SDK with native rendering.
Who it's for: teams building reader UX on iOS + Android.
When to use: you need native PDF performance and shared UI logic.
When not to use: you only need web rendering.
Packages
@papyrus-sdk/engine-nativefor iOS (PDFKit) and Android (PDFium)@papyrus-sdk/ui-react-nativefor the viewer, sheets, and toolbars
Status
- PDF rendering stays native (Android PDFium + iOS PDFKit).
- EPUB/TXT render inside a WebView runtime (epub.js + DOM) while keeping the same UI shell.
- Text search and selection are handled per engine.
- UI is built in React Native and mirrors web flows.
- Expo prebuild is supported via
@papyrus-sdk/expo-plugin.
Mobile UX baseline (reference for Web and RN)
For small screens, keep this interaction baseline:
- Header keeps key actions visible.
- Left side: menu button (thumbnails) plus a pencil button to open/close the annotation dock.
- Center: page navigation stays centered.
- Right side: search sits next to the
...overflow button. - Remove long branding on mobile (for example
PapyrusCore) to prioritize title and controls.
... quick actions modal:
- Include zoom controls (
-and+) with current percentage. - Include page theme options.
- Include UI theme toggle with an icon.
- Include upload action with an icon.
- Do not duplicate search inside the modal when search is already visible in the header.
- Keep the modal open after page/UI theme changes.
- Enforce readable border/text contrast (avoid black-on-black).
Layout behavior:
- Thumbnail and search side panels should open as overlays, not push the page rendering sideways.
- Viewer should support pinch-to-zoom (two-finger gesture) on touch devices.
- Annotation dock should start closed and open only via explicit action (pencil button).
- If the dock closes, nested popovers (for example color picker) should close too.
- Bottom sheet/modal must render above the annotation dock (higher z-index/layer).
Document types
DocumentType includes: 'pdf' | 'epub' | 'text'
Use the new load request to force the type:
import { MobileDocumentEngine } from '@papyrus-sdk/engine-native';
const engine = new MobileDocumentEngine();
await engine.load({ type: 'epub', source: { uri: 'https://example.com/book.epub' } });Compatibility is preserved: engine.load(source) still works and the type is inferred from URI extension or data URI mime (fallback to pdf).
WebView requirement
EPUB/TXT require react-native-webview in the host app:
npm install react-native-webviewFor RN CLI apps, make sure Metro treats html as an asset so the runtime can load:
// metro.config.js
resolver: {
assetExts: [...assetExts, 'pdf', 'html'],
},When loading EPUB/TXT, render <Viewer /> before awaiting engine.load(...) so the WebView runtime can initialize.
Notes
Mobile requires native build steps (Xcode / Android Studio). Examples live in:
examples/mobile(RN CLI)examples/mobile-expo(Expo + prebuild)
Build all packages before running the examples:
pnpm -r --filter "./packages/**" --sort --workspace-concurrency=1 buildAndroid APK (RN CLI example):
cd examples/mobile/android
./gradlew assembleReleaseInstall on emulator/device:
adb install -r app/build/outputs/apk/release/app-release.apk