“Let people open the attachment without leaving the app” sounds like a small request. The team already stores the file. The browser can display a PDF. It goes into a sprint estimate without much debate.
For a while, the answer may be: not much. The demo works, the ticket closes, and everyone gets on with the features customers are actually paying for.
Then the documents start coming from customers instead of the test folder. One is a scan, another has 200 pages, and someone needs to see the comments their colleague left yesterday. Suddenly the harmless-looking preview has a backlog of its own.
The files people send are rarely tidy
A developer can get a PDF onto a screen without much fuss. Getting every PDF onto the screen is a different job. Business documents come out of accounting programs, old scanners, phone cameras, and office software that hasn't been updated in years. Odd fonts, landscape tables, password protection, and form fields are all perfectly ordinary things to encounter.
In a React-based customer portal, a team might build a custom React PDF viewer around a few clean sample files and get a convincing result. The expense shows up when customers expect the same viewer to let them copy text from an invoice, search a contract, print the correct pages, or complete a form. Each behavior needs to work with the documents people actually upload, not just the ones used in the demo.
Take an agreement that's been signed, scanned, and emailed back. It looks readable. But the page may contain no searchable text at all; to the application, it's an image. Adding optical character recognition helps with that, although it brings decisions about when recognition happens and what to do with blurry scans or misread names. A customer searching for a termination clause isn't interested in why the search fails. They need to find the clause.
Speed becomes a separate cost. A three-page receipt and a 200-page report with photos, diagrams, and embedded fonts won't behave alike. Rendering too much at once can strain a laptop or freeze a phone. Making the experience tolerable may mean loading pages on demand, managing memory, and testing on devices the engineering team doesn't use every day.
This is where business analysis in digital transformation earns its keep. Asking which files customers open, how large they are, and what people do after opening them sounds dull compared with shipping a feature. It's also the difference between estimating the job and estimating a nice-looking screenshot.
The quiet costs: keeping files private and making them usable
Security often gets budgeted as though it stops at the login page. Imagine a supplier portal where one company uploads pricing agreements and another company must never see them. The PDF viewer is only one part of that arrangement. Every request for a file needs the right permission checks, including requests made through an old link, a shared browser, or a user account whose access has changed.
Uploads introduce their own problems. A file called contract.pdf might not contain the kind of file the application expects. Very large uploads can waste resources. Storage locations, download links, and temporary copies all need thought. OWASP's guidance on file uploads lays out precautions including validation and size limits. Those aren't glamorous features, but somebody has to build them, test them, and keep them working.
The extra cost can hide in the handoffs. A developer changes how files are fetched, the security review flags an access problem, and the team has to revisit code it considered finished. When the documents contain contracts, employee information, or financial records, “we'll tighten it up later” is a difficult position to defend.
Accessibility tends to be overlooked for a different reason: the people approving the demo may all use the same kind of computer. If nobody tries the viewer with a keyboard, the toolbar may be impossible to navigate without a mouse. If the controls aren't labeled properly, a screen reader may give the user a row of unhelpful buttons.
The Web Content Accessibility Guidelines address keyboard access and other interface requirements. But there's a limit to what an accessible viewer can fix. A scanned document without recognized text, or a PDF with a badly arranged reading order, can remain difficult to use. For an education portal or employee system, the team may need a way to check the documents as well as the viewer.
The comment box makes everything more complicated
At some point, someone asks if the app can support comments. Usually they're picturing a yellow highlight and a little note beside it. That part looks manageable. It's the life of the note that gets complicated.
Say a purchasing manager highlights a sentence in a supplier contract. A colleague should see the comment later, ideally in the same place. Whether the highlight survives a download matters, as does who can read it. Internal remarks may need to stay hidden from suppliers. Two reviewers can also have the same file open at once, and the app needs a rule for handling their changes. These decisions have to be settled before the feature is dependable.
Storing a comment in a database is straightforward compared with keeping it attached to the right piece of text as documents change. The team may need to deal with rotated pages, revised layouts, and multiple versions of the same contract. Support will need a way to investigate complaints such as “my comments disappeared,” which are especially hard to untangle without a record of what happened.
Then approvals get involved. In a procurement workflow, finance might approve a draft on Tuesday and receive a revised copy on Wednesday. The app should be able to say which version was approved, by whom, and whether the approval still applies. A green checkmark next to a filename won't answer that.
Being able to compare changes between PDF versions can help someone catch a revised price or a missing clause. It doesn't remove the need to keep earlier drafts, link comments to the correct files, and preserve the approval history. Once decisions are being made inside a document, an apparently simple viewer has become part of the company's records.
Someone will still own it a year from now
The seventh cost is maintenance, and it rarely appears clearly in the original estimate. Browsers change. Dependencies need updating. A customer reports that a document opens in Chrome but fails on an older tablet. An engineer who was meant to be working on billing or reporting spends the afternoon trying to reproduce it.
The requests don't stop either. Customers ask for signatures, mobile improvements, better search, or a way to put two drafts side by side. Some are reasonable additions. Others belong well outside the product's priorities. But even saying no takes a bit of investigation when a sales team wants to know whether the feature is possible.
Buying a ready-made component changes the bill; it doesn't make the bill disappear. There may be license fees, limits on customization, integration work, and future vendor changes to manage. The discipline behind matching software features to business needs is useful here: a customer portal that displays occasional receipts shouldn't be priced or designed like a contract-review system. Equally, a document-heavy product shouldn't assume a free preview will remain sufficient once customers depend on it.
It's worth putting support and updates beside the initial build estimate. Those hours are easy to leave out because nobody sends the business a separate invoice when its own engineers do the work.
Wrap-up takeaway
There's nothing wrong with building a PDF feature yourself, provided the estimate reflects what people will ask it to do. For some apps, opening and downloading a file really is enough. For others, search, access controls, annotations, and approval history become everyday requirements, with ongoing work attached to each one. The expensive mistake is choosing an approach based on a demo and treating everything after launch as an exception. Pick five documents customers have actually sent you, note what they need to do with each file, and have the team estimate that work before committing to a build.