A PDF viewer rarely arrives on a product roadmap looking dangerous.
The request usually sounds small: open a document inside the app, let the user zoom, maybe add a download button. Someone estimates a couple of days. A package gets installed. The first sample PDF appears on screen, and everyone moves on.
Then a customer uploads a 180-page contract. Legal wants annotations. Sales asks for signatures. Mobile users complain that pinch-to-zoom feels terrible. Someone discovers that scanned documents don’t have searchable text. Suddenly the PDF viewer isn’t a viewer anymore. It’s part of the product.
That change is where the build-versus-buy decision gets interesting.
Start with what “viewing a PDF” actually means
Before choosing a library, write down what users are supposed to do after the file opens. That sounds obvious, but teams often define the requirement as “display PDFs” when the real workflow is closer to “review a document, find a clause, leave comments, fill three fields and send it back.”
A React PDF viewer can begin as a component mounted inside an existing interface, but the technical footprint changes quickly once the viewer needs annotations, forms, search, signatures or reliable rendering of complicated files. Each extra capability affects what you’re really choosing: a renderer, a collection of libraries, or a document system embedded inside your app.
A claims-management product is a good example. An adjuster opening a five-page statement may only need zoom and page navigation. The same adjuster opening a 90-page medical record may expect full-text search. Give them a construction-loss report and they may want to draw on an image, add a note and save the marked-up copy. “PDF support” describes all three cases while hiding most of the engineering work.
This is partly a requirements problem. Techidemics has already looked at how poorly defined software requirements create expensive downstream problems, and document features are especially good at exposing them. A developer can satisfy the literal ticket while still building something users consider unfinished.
The useful questions are more specific. Do people only read files, or modify them? Will documents be 500 KB or 200 MB? Are they mostly clean PDFs exported from Word, or scanned paperwork from a phone? Do users expect text selection, thumbnails, keyboard shortcuts, comments, signatures or offline access?
Those answers should come before the package search.
Building is cheap when the requirement stays small
For straightforward viewing, building on an open-source foundation can be completely reasonable.
Mozilla’s PDF.js project gives developers a mature way to parse and render PDFs in the browser. If your product needs a tightly controlled interface with page rendering, navigation and a few custom controls, using a lower-level library can keep the UI lean and avoid paying for features you don’t need.
The catch is that “custom” has two meanings. You get complete control, but you also become the team responsible for everything surrounding the rendering engine.
Take search. Drawing pages is one job. Extracting text accurately, highlighting matches, moving between results and handling documents with no usable text layer is another. Annotations add their own storage model, permissions and import/export questions. Forms introduce field behavior and persistence. Accessibility has to survive your custom controls. Touch interaction needs testing independently of the desktop experience.
None of these problems is impossible. They simply accumulate.
Scanned documents make the difference particularly visible. A phone can now replace a surprising amount of office scanning hardware, as Techidemics noted in its comparison of mobile scanners and traditional scanners. But the files coming out of that workflow aren’t necessarily neat, text-native PDFs. You may get rotated pages, photographs wrapped in PDF containers, odd dimensions, compression artifacts and documents that require OCR before search means anything.
The sensible build case is therefore narrower than “we have React developers.” Build when the required experience is genuinely limited, the team wants unusual UI behavior, and owning the document layer is an acceptable long-term responsibility.
If version one already includes twelve toolbar buttons and a list of “later” features involving redaction, signatures and collaboration, the calculation has probably changed.
Embedding saves engineering time, but you still own the product decision
The middle ground is to embed a more complete viewer or SDK rather than assemble every document feature yourself.
This can remove months of low-level work, especially when the product needs mature behaviors such as annotations, form filling, search, page manipulation or multiple document formats. But buying a deeper component doesn’t mean the integration becomes a copy-and-paste exercise.
Your app still needs to decide who can see each document, where saved changes go, what happens when a session expires, whether an annotation belongs to one user or the whole team, and how the viewer behaves inside the rest of your interface.
There are also less obvious costs.
A document engine can add a meaningful amount of JavaScript or WebAssembly to the browser. Loading all of it on every route would be wasteful if only 15 percent of users ever open a document. React’s own documentation describes how lazy can defer component code until it is first rendered, and document-heavy features are a good candidate for that kind of separation. Loading strategy matters once the viewer becomes one feature inside a much larger application.
Licensing deserves the same attention as performance. Compare pricing against actual usage rather than the smallest number shown on a pricing page. Does cost depend on developers, deployments, users, documents or servers? What happens when the app moves from an internal tool used by 80 employees to a customer-facing product used by 20,000 people?
Then look at exit cost. If annotations are stored in a proprietary format, can you export them? If the viewer controls document editing, how difficult would migration be two years from now? Can your team replace the interface without rewriting the surrounding workflow?
Those questions aren’t arguments against commercial components. They’re how you avoid mistaking a fast integration for a cheap architecture.
The same trade-off shows up elsewhere in software development. Techidemics’ discussion of cloud strategies for modern developers makes a similar point from another direction: convenience at one layer changes responsibilities elsewhere. With document tooling, you are often buying back developer time, not buying your way out of architectural decisions.
Test the ugly files before choosing anything
Demo PDFs are almost useless for evaluating a viewer.
Every option looks good when the test document is eight pages of clean text with a logo at the top. The problems appear when the file resembles what customers actually upload.
Build a test folder before making the decision. Twenty or thirty documents can tell you more than hours spent comparing feature tables.
Include a large contract. A scan from an old multifunction printer. A phone scan. A PDF with hundreds of pages. One with embedded fonts. A form. A file containing comments. A password-protected document if your product accepts them. Try something with mixed page sizes and another with oversized engineering drawings if that’s remotely plausible for your users.
Then test workflows rather than features.
Open page 87 from a search result. Rotate a page, close the viewer and reopen it. Add ten annotations and scroll quickly. Resize the browser repeatedly. Try the same file on a mid-range phone, not just a developer’s new laptop. Disconnect the network after the document loads. Check what happens when two users touch the same saved document.
Uploads deserve separate scrutiny. If users can provide their own PDFs, the viewer sits downstream from a security boundary. The OWASP File Upload Cheat Sheet recommends controls including allowlisting expected extensions, checking file signatures, limiting file sizes and treating uploaded content as untrusted. A slick viewer doesn’t compensate for a careless upload pipeline.
Performance numbers should also come from your application. A viewer that opens a 100 MB PDF quickly in isolation may behave differently beside your analytics scripts, authentication layer, chat widget and the rest of the production bundle.
Finally, give the prototype to the people who will actually use it. Developers notice console errors. Users notice that the search result jumps to the wrong place, the toolbar takes up half a phone screen, or they can’t figure out how to return to the previous page. Those are product problems, and they often decide whether the integration feels finished.
Wrap-up takeaway
There isn’t a universally smart choice between building, embedding and buying PDF functionality. The right answer depends on how far the document workflow extends beyond putting pages on a screen. Building gives you control, but every extra capability becomes something your team must design, test and maintain. A fuller component can remove a large amount of engineering work, but licensing, loading behavior, data flow and migration still deserve scrutiny. The expensive mistake is choosing based on a clean demo and discovering the real requirements after the viewer is already buried in the product. Take ten representative customer documents today, write down the five things users actually need to do with them, and use that small test set to evaluate your options before anyone commits to an architecture.


