react-native-file-viewer

Native file viewer for React Native that hands a local file to the OS's own preview or app-chooser on iOS, Android, and Windows.

Library
npm
v2.1.5
448stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
37/100Needs Attention
Development Activity0
Maintenance0
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
45/100Fair
Architecture65
Code Quality40
Innovation30
Learning Curve45

react-native-file-viewer is a thin native-module bridge that lets a React Native app preview any file the device already knows how to open, without shipping a custom in-app viewer. Call FileViewer.open(path) and the library hands the file off to the platform’s native viewing surface: Apple’s QuickLook framework on iOS, an ACTION_VIEW intent resolved through a FileProvider on Android, and the OS-associated app on Windows.

Because it delegates to whatever viewer the device already has installed, it supports PDFs, images, Office documents, and any other format the OS recognizes, with zero format-specific rendering code in the library itself. It’s commonly paired with a document picker or a downloader (react-native-document-picker, react-native-fs) that first gets a file onto local disk.

What You Get

  • A single cross-platform open(path, options?) API that resolves or rejects a promise based on native RNFileViewerDidOpen/RNFileViewerDidDismiss events
  • iOS preview backed by Apple’s QuickLook framework (QLPreviewController), including a customizable displayName for the preview title
  • Android preview via an ACTION_VIEW Intent resolved against a FileProvider, with an optional showOpenWithDialog app chooser and showAppsSuggestions Play Store fallback when no app can open the file
  • Windows support that launches the file in whatever application is associated with its extension
  • TypeScript type definitions (index.d.ts) shipped alongside the JS module
  • An onDismiss callback so the app can react when the user closes the native preview

Common Use Cases

  • Previewing a PDF, image, or document downloaded to disk with react-native-fs before the user shares or prints it
  • Opening a file just picked with react-native-document-picker or react-native-image-crop-picker without writing a custom viewer
  • Letting a user inspect an attachment (invoice, receipt, contract) generated or cached by the app
  • Building a document-management or field-service app where the file’s origin app should render it (Office docs, CAD files, etc.) rather than the RN app itself

Under The Hood

Architecture The library is a minimal native-module bridge: index.js exposes a single open() function that normalizes the file path, then either calls the native module directly (non-mobile platforms) or wraps the call in a promise keyed by an incrementing request id, listening for RNFileViewerDidOpen/RNFileViewerDidDismiss events via NativeEventEmitter so the JS side can resolve/reject and fire an onDismiss callback once the native viewer is closed. There’s no internal layering beyond this JS-to-native boundary — each platform (android/, ios/, windows/) implements its own self-contained native module with the same event contract, so the design is a straightforward one-function bridge rather than a multi-module system. The main coupling risk is the event name/id contract staying in sync across the four platform implementations.

Tech Stack The JS surface is untyped JavaScript with a hand-written TypeScript declaration file (index.d.ts) rather than a TS source build. Native implementations are platform-specific: Java on Android (ReactContextBaseJavaModule, AndroidX FileProvider, Intent.ACTION_VIEW, MimeTypeMap), Objective-C on iOS (QLPreviewController/QLPreviewControllerDataSource from the QuickLook framework), and C# on Windows (a .csproj-based React Native Windows module). Packaging follows standard React Native conventions — a CocoaPods podspec for iOS, a Gradle build.gradle for Android — with react-native itself declared only as a peer dependency, so the library carries no runtime npm dependencies of its own.

Code Quality No test files or test framework are present anywhere in the repository — the package.json test script simply exits with an error, and there’s no CI configuration (no .github/workflows or equivalent). Error handling in both native modules is explicit: the Android module surfaces failures (missing activity, invalid file, no resolving app) back to JS as rejected-promise messages via the same event channel used for success, and the iOS implementation is a small, direct QuickLook wrapper with little branching logic to go wrong. Naming is consistent and the public surface is deliberately narrow (one function, one options object), which limits the blast radius of the missing test coverage.

What Makes It Unique The library doesn’t render or convert files itself — it delegates entirely to the OS’s own viewing surface (QuickLook, an Android ACTION_VIEW chooser, or Windows file associations), which means it inherits whatever format support the device already has rather than shipping and maintaining per-format renderers. This makes it lightweight compared to alternatives that bundle their own PDF or document renderers, at the cost of the preview looking and behaving like the native OS viewer rather than a themeable in-app component.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search