Articles · App ExamplesUpdated September 2026

Add a PDF viewer to an app in an afternoon, or in a sprint.

There are two real ways to add a PDF viewer to an app, and the cheap one is usually right. Either you hand the file to the viewer the phone already has, or you render it yourself inside one of your own screens. The first is a few lines and no design control. The second is a dependency, a loading state and a memory budget. If the user picks the file first, that is a separate job, and it is covered in adding a file picker.

The honest limit up front: there is no one PDF view that behaves the same on both platforms. Apple has shipped a complete one since iOS 11. Android's built in class renders a page at a time into a bitmap, and the platform reference says selection, search and annotations arrive in Android V, the release numbered 15. Anything that looks identical on both is a library somebody added.

See which route fits your file

The short version

Handing the document off is nearly free, keeping it inside is where the work is.

One question decides this, and it is not a technical one. Does anything have to happen around the document? A watermark, a disabled share button, a line in the audit log, a form beside page 14. If nothing does, hand the file off and spend the week on something else.

If something does, you are building an in app document viewer. The cost is a dependency, a cache and a test pass on both platforms with your largest file. The last one catches people out.

Hand it off, or draw it yourself

Handing off means the operating system shows the file and your app steps back. On iOS that is the preview behind Quick Look and the share sheet. On Android it is an intent that any installed PDF app can answer. You write very little, the reader gets a viewer they already know, and your app goes to the background while they read.

Rendering means a view inside your own screen. You keep the navigation bar, the back button and the branding. You can watermark a page, hide the export button, log that a contract was opened, and put a question beside the clause it is about. None of that is possible once the file has left your app.

So the rule is short. To open a PDF in a mobile app and nothing more, hand it off. To display a PDF in an app that also has an opinion about who sees it, render it. Teams that regret this choice usually picked rendering for a document nobody was going to touch.

The handoff has one failure mode worth testing on a device rather than assuming. On Android the intent needs an installed app that accepts PDFs, and a phone with none will do nothing at all. Handle that case, even if it is only a message.

Try it

Which route fits your document

Three answers settle it. Tick the ones that are true of your file.

Hand it to the system viewer

Nothing to build, and people already know the viewer their phone opens. Cost: no new dependency.

On iOS most of the viewer already exists

Apple ships PDFKit, a system framework whose stated job is displaying and manipulating PDF documents in your apps. It has been on iOS since iOS 11 and on macOS far longer. You are not handed a rendering primitive, you are handed the viewer. There is PDFView for the document, PDFThumbnailView for the page strip, and objects for the page, the outline, text selection and annotations.

That changes the estimate. On iOS a scrolling, zoomable, selectable document screen is mostly configuration. It is not a component you have to invent.

Android sits at a lower level, and pretending otherwise is how a two day job becomes a two week one. Cross platform packages exist to paper over that gap, and most pair Apple's view with a separate Android renderer. Worth knowing before you read a feature list, because the two halves do not always match.

Apple Developer, PDFKit framework reference

Loading the file is the part that gets slow

A PDF is not an image. It is a document format with fonts, vector artwork and sometimes scanned pages at print resolution, so turning one into pixels is real work. Android's own reference says the renderer's constructor can be long running while it loads the document, and that it belongs on a worker thread. Do it on the main thread and you have shipped a freeze.

The same page sets out the model. Open the document, open a page, render it, close the page, and only a single page may be open at any given time. Every smooth scrolling PDF screen on Android is a cache built on top of that. The cache is what separates a document that flicks from one that stutters. Treat it as ordinary app performance work, because that is what it is.

Two more details from that reference are easy to miss. A password protected file makes the renderer throw a security exception, unless you pass the password in through the newer constructor. For a file from an untrusted source, Android recommends running the renderer in a separate, isolated process with minimal permissions. If your app opens PDFs that other people upload, that is most of your security review.

Android Developers, PdfRenderer API reference

Some documents should not leave your app

The handoff route has a property that stays invisible until somebody audits you. Once the file is in the system viewer it is in the share sheet too. From there it can go to mail, to a chat, to a personal cloud drive. You did not decide that and you cannot see it happen. Fine for a restaurant menu. Not fine for a discharge summary.

This is the usual reason a team pays for the rendering route. Keeping the document inside your own view lets you decide there is no export button, stamp each page with the account that opened it, and write one line saying who opened what and when. Anything with the word compliance near it, a patient record or a hipaa compliant fax app, ends up here for exactly that reason.

Be honest about the ceiling though. A rendered page can still be photographed with a second phone, and a file you downloaded is a file on the device. In app rendering buys you a defensible default and a trail you can show somebody. It does not buy you control of a document after a person has read it.

Five ways to show the file, and what each one costs

ApproachStays inside your appOpens a stored fileText selection and searchNo native code
Hand off to the system viewerNoYesthe viewer'sYes
In app browser taba sheet on topNothe browser'sYes
Platform PDF viewYesYesiOS yes, Android 15 and upNo
JavaScript renderer in a web viewYesif you bundle itYesYes
Page images rendered on your serverYesNoNoYes

Building the viewer into an app you own

When the document is the point of the app rather than a footnote in it, the viewer stops being a feature and becomes the product. That is usually when people stop bolting a PDF onto something. They start describing the whole thing around the document: a list of files, a viewer, a signature, a record of who read what.

Newly is an AI app builder. You describe the app in plain English and it writes a real React Native and Expo project you own, runs it on a cloud iPhone or Android simulator while it builds, and ships it to TestFlight and to Google Play internal testing. It is $25 a month and there is no free plan. The code leaves as a ZIP from Settings or through two way GitHub sync. That matters here, because adding a native PDF package is a change in the project rather than a box you tick.

Whatever route you pick, settle one thing early: does the document have to open with no signal? That answer changes the storage, the cache and the first screen. Start with reading it offline before you choose a viewer.

Questions people ask about PDF viewers in apps

Two routes. Hand the file to the system viewer, which is a few lines of code, or render the document inside one of your own screens. Pick the first unless something has to happen around the document, such as a watermark, a hidden export button or an audit line.

Describe the document screen, not just the file

Write down where the file comes from, who is allowed to see it, and whether it has to open with no signal. Build the screen around those three answers.

Start building