Skip to content

Releases: gmi-software/react-native-better-pdf

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 12:10
1e313be

1.1.0 (2026-10-19)

1.1 adds two ways to open documents, both requested in issues: several files
shown as one document (#5, #60)
and base64 strings (#6, #42).
It also makes long documents cheaper on both platforms, and raises the minimum
React Native version to 0.83.

Highlights

Several documents as one — source={[a, b, c]} shows the files one after
another as a single document: one page count, zoom, layouts, paging and search
across all of them. Each source can carry its own password. onLoad's
sources says where each file's pages start; the set loads all or nothing,
and onError's error.sourceIndex says which file failed. Links within a
file lead to its pages, and "next page" / "previous page" links cross into the
neighbouring file. The set is for reading: print, exportDocument and form
filling need one file and reject with several sources.
Guide

Base64 documents — source={{ base64 }} opens a PDF you have as a string
(pdfmake, pdf-lib, an API response), in PdfView and PdfDocument.open. It is
decoded natively off the main thread, and no file is handed to the app
(filePath is undefined). Meant for documents up to a few MB; no data:
prefix.
Guide

Lighter on long documents (simulators and emulators; methods and every run
in docs/performance/results.md):

  • Android: text pages and greyscale scans are kept at one byte per pixel, a
    quarter of the memory. Peak PSS on 500 greyscale scans: 144.7 → 110.4 MB (§20).
  • Android: zoomed out below the fitted width, pages render at half or a
    quarter size. 1,000 pages at zoom 0.05: peak PSS ~240 → ~150 MB (§17).
  • Android: page bitmaps are reused in landscape, on tablets and on unfolded
    foldables; a trip to the background no longer counts as memory pressure;
    on Android 7.x, colour pages no longer run out of memory on small Java
    heaps (§21).
  • iOS: search highlights no longer block the main thread. With 528,449
    matches, next/previous went from 1.23–1.34 s to 10–19 ms (§15).
  • iOS: forms on long documents stay off the main thread. On 5,000 pages,
    getFormFields after an edit went from 3.24 s to under 0.1 ms (§19).

⚠ BREAKING CHANGES

  • React Native 0.83+ (Expo SDK 55+) is required. On React Native 0.81,
    iOS never tears down a closed viewer, so every closed PdfView kept its
    document, search and form in memory; no Expo SDK ships 0.82. Apps on Expo
    SDK 54 can stay on 1.0.1. (#58, closes #26)

Upgrading

  • PdfLoadEvent has a new required sources array (one entry per source, so
    one for a single source). A test that builds an onLoad payload typed as
    PdfLoadEvent needs it. (#60)

Behavior changes

  • iOS: goToPage, goToViewport and zoomTo called from onLoad while
    the view has no size yet apply once it is laid out (the view used to open at
    the initial page and zoom); such a zoom is reported through onScaleChange
    after the first layout. (#46)
  • Android: fractional page numbers are rounded, not truncated, as on iOS:
    goToPage(1.6) opens page 2. Also goToViewport, initialPage and
    initialViewport.page. (#37)
  • Android: search() before onLoad is ignored with no event, as on iOS
    (it emitted an empty finished search, then a cleared one). (#55)
  • Android: page-render-failed is reported only when the immediate retry
    fails too; a page whose zoom tiles fail keeps its base bitmap. (#55)
  • Android: for accessibility services other than screen readers, page text
    is read on demand, not ahead for every visible page. (#55)
  • Android 12–14 with SDK extension 13: a long press selects text and
    onTextSelectionChange fires, as on Android 15+ (long presses were
    ignored). enableTextSelection={false} turns it off. (#57)
  • Android: the view's renderPage, getOutline and getPageSizes run one
    at a time in call order, as on iOS and in PdfDocument; exports run on a
    thread of their own. Calls still queued when the document closes or is
    replaced reject with "The document was closed". (#41)
  • Android: reading a malformed file's outline, links and metadata is
    bounded in time. A read over the budget fails as a whole instead of
    returning partial results: links fall back to the renderer's, and
    getOutline / getMetadata reject. Damaged files with cross-reference
    streams, which failed with "No document catalog", are now read. (#38)
  • Both: exportDocument into the download cache's directories rejects
    ("The export path is in the cache of downloaded documents"). On iOS,
    exporting over a remote document's onLoad filePath rejects too; it used
    to overwrite the cached copy. (#45)
  • iOS: print() rejects with "The document was closed" when the view
    closes or its source changes while a protected or filled-in document is
    prepared; the dialog used to open anyway. (#40)
  • iOS: AES-128 documents print without a second password prompt (cancelling
    it crashed the app). The in-memory print copy of a protected document is
    always re-encrypted with AES-128. (#39)
  • iOS: a filled-in export of a protected document is re-encrypted with
    AES-128 and an owner password nobody knows, so its restrictions can't be
    lifted; an AES-256 original comes out AES-128. Android keeps the document's
    own encryption. (#37)
  • iOS: a negative or infinite pageSpacing falls back to 8 (was 0 /
    infinite). (#37)
  • iOS: getStats() returns -1 for the counters it cannot measure
    (cacheHits, cacheMisses, bitmapAllocations, pagesRendered,
    rendersCancelled), not 0. (#37)
  • iOS 17+: an existing %XX escape next to a character that needs encoding
    is kept: My%20File 2.pdf → My%20File%202.pdf, not My%2520File%202.pdf.
    (#37)

Features

  • open documents from base64 strings (#42) (8440ced), closes #6
  • show several PDFs as one document with source={[a, b, c]} (#60) (e7f38eb), closes #5

Bug Fixes

  • apply navigation from onLoad once a zero-size iOS view is laid out (#46) (4ce915f), closes #43, references #1
  • bound the time the Android parser takes on malformed PDFs (#38) (3d42e4a), closes #27
  • enable text selection on Android 12–14 with SDK extension 13 (#57) (b1581d4), closes #25
  • ios: keep form reads, edits and exports of long forms off the main thread (#28) (#48) (a0c4944)
  • keep the reader's page when a running iOS search is stopped (#33) ([4b935ad](4b935ad36f2ef10e6...
Read more

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 14 Oct 18:23
3ec3fd9

1.0.1 (2026-10-14)

Behavior changes

  • iOS: a source or password change now clears an active search when the reload starts, so the cleared onSearchChange comes then instead of after the next successful load. Android already did this. (#16)

Bug Fixes

  • bound nested object reads in the Android PDF parser (#12) (6f1ce53)
  • clear the Swift capture and Gradle syntax warnings (#10) (4c9a329)
  • drop download progress after an abort (#11) (00cb534)
  • keep the Android render thread alive after an Error (#15) (bc0ef22)
  • reject export paths that name a directory (#8) (e579a60)
  • reject invalid request headers instead of crashing on Android (#13) (aea60fb)
  • release closed viewers and their documents (#16) (9d75bda)
  • stop crashing on invalid page numbers (#14) (bb50ffb)

v1.0.0

Choose a tag to compare

@jkasprzyk17 jkasprzyk17 released this 12 Oct 15:38

First public release: a native PDF viewer for React Native's New
Architecture, on PDFKit (iOS) and PdfRenderer (Android), with no JS in
the scroll, zoom and render path.

  • Viewing: local files, bundled assets (require()) and downloads;
    vertical continuous, horizontal and paged layouts, single page, right to
    left, facing pages; fit policies, pinch and double-tap zoom, initial page
    and scale; contentInset for translucent bars; rounded cards; dark
    pages.
  • Navigation and events: page changes, settled viewport events with
    restore on open or on demand, end-of-document detection; link presses
    and page taps in PDF points; the outline (getOutline).
  • Text: search with highlighted matches; text selection with the
    platform's handles and Copy / Select all.
  • Forms: filled in by touch or from code, read back by field name,
    exported as a filled-in PDF.
  • Page overlays: React views attached to points of a page
    (PdfPageOverlay), moved natively while it scrolls and zooms.
  • Documents without a view (PdfDocument): page count, metadata, page
    sizes, outline and page images.
  • Offline: downloads kept for the session or across launches,
    revalidated with ETag / Last-Modified, shown when offline;
    PdfCache downloads ahead of time and manages copies.
  • More: page images (renderPage), printing, password-protected
    documents, screen reader support, typed errors, load progress.
  • Android below 15: links in every form are read from the file on
    every Android version; Android 12–14 with SDK extension 13 also get
    passwords, search, text selection and forms through PdfRendererPreV.

Requirements: React Native 0.81+ (New Architecture),
react-native-nitro-modules 0.37+, iOS 15.1, Android API 24, Expo SDK 54+
development builds. What depends on the Android version is listed under
Limitations.