PDF.js limitations: When to upgrade to a commercial PDF SDK
Table of contents
PDF.js handles basic PDF rendering in the browser, but it lacks features that production applications eventually need. Signs you need a commercial PDF SDK include:
- Users report blurry text, broken barcodes, or washed-out colors
- You’re building annotation, form, or signature features from scratch
- Security audits flag missing encryption or access controls
- Large documents crash browsers or freeze the UI
- Your team spends more time maintaining PDF code than shipping product features
If three or more of these apply, a commercial SDK will cost less than building and maintaining these features yourself. Nutrient Web SDK is a commercial PDF.js alternative designed as a drop-in replacement.
PDF.js is widely adopted. Mozilla’s open source viewer is the built-in PDF reader in Firefox and is embedded in many web applications.
But requirements expand from viewing to annotation, signatures, and collaboration — and PDF.js doesn’t support these workflows.
Where PDF.js works well
PDF.js works for specific use cases:
- Read-only document portals — Displaying invoices, receipts, or reports that users view but don’t modify.
- Prototyping — Getting a PDF viewer running quickly to validate a product idea.
- Low-traffic internal tools — Administrative dashboards where a handful of users view simple documents.
- Budget-constrained projects — When the budget for third-party libraries is zero and the feature requirements are minimal.
If these scenarios describe your application and users aren’t reporting issues, PDF.js is sufficient.
Five signs you’ve outgrown PDF.js
These are the most common indicators that PDF.js is no longer sufficient for your application. If three or more apply, it’s time to evaluate a commercial SDK.
1. Users report rendering problems
PDF.js renders documents by parsing PDF content and drawing it onto an HTML5 <canvas> element. This works for simple layouts but produces rendering errors on complex documents.
Users most commonly report these issues:
- Washed-out colors — PDF.js has a long-standing color rendering issue(opens in a new tab) that has been open for more than 13 years. Recent versions added partial ICC color profile support, but documents that render correctly in Adobe Acrobat or Preview still appear faded in PDF.js.
- Broken barcodes and QR codes — Font rendering inconsistencies cause barcodes to become unscannable. For applications that generate shipping labels or tickets, this is a production blocker.
- Missing or incorrect gradients — PDF.js has multiple open issues related to shading patterns(opens in a new tab) and soft masks. Documents with complex graphics render incorrectly.
- Blurry printed output — Because PDF.js rasterizes content through canvas, printed documents lose sharpness(opens in a new tab), and text becomes pixelated instead of remaining vector-based.
If your support queue includes “the PDF looks wrong,” check PDF.js rendering first.
2. You’re building features that should be built in
PDF.js is a viewer. It renders pages and supports text selection. Annotations, forms, signatures, redaction, and page manipulation all require custom code.
This table shows what PDF.js includes and what requires custom development.
| Feature | PDF.js | Custom build required? |
|---|---|---|
| Render and view PDFs | Yes | No |
| Text search | Yes | No |
| Highlight, ink, stamp, free text, signature annotations | Yes (five types) | No |
| Shape annotations (arrows, circles, lines) | No | Yes |
| Sticky notes and comments | No | Yes |
| Annotation import/export (XFDF) | No | Yes |
| Interactive form filling | Partial | Yes, for validation and submission |
| Form creation | No | Yes |
| Electronic signatures | Partial | Yes, for workflows and verification |
| Digital signatures (PKCS#7) | No | Yes |
| Page manipulation (reorder, merge, split) | No | Yes |
| Redaction | No | Yes |
| Real-time collaboration | No | Yes |
| Measurement tools | No | Yes |
| Office file viewing (Word, Excel, PowerPoint) | No | Yes |
| OCR (text extraction from scanned PDFs) | No | Yes |
| Document comparison | No | Yes |
| AI-powered document processing | No | Yes |
| WCAG 2.2 AA accessibility | Partial | Yes, for full compliance |
Development time per feature ranges from weeks to months (see the cost comparison below). Maintenance cost compounds with each browser update, PDF spec revision, and framework upgrade.
3. Security or compliance requirements are growing
PDF.js has no built-in security features. It provides no mechanisms for:
- Document encryption — PDF.js can open password-protected PDFs, but it cannot create or apply AES or RC4 encryption to protect content at rest.
- Access controls — No permission system to restrict printing, copying, or editing.
- Digital rights management — No way to enforce document-level restrictions.
- Audit trails — No logging of who viewed, annotated, or signed a document.
In May 2024, CVE-2024-4367(opens in a new tab) allowed arbitrary JavaScript execution through malformed font data in PDF.js. It affected every Firefox version below 126 and every website embedding an unpatched version.
Commercial SDKs also have vulnerabilities. The difference is dedicated security teams, defined patch cycles, and coordinated disclosure — requirements for applications that handle legal, medical, or financial documents.
4. Large documents crash or freeze the browser
PDF.js processes everything on the client side. The browser’s main thread handles parsing, rendering, and painting to canvas. Documents under 10 MB with simple layouts render without issues. Larger or complex files cause problems.
The following issues are well documented:
- Memory consumption — A reported case(opens in a new tab) showed PDF.js consuming 3 GB of memory for a document that Adobe Acrobat handled in 650 MB. The underlying issue — lazy page rendering for large PDFs(opens in a new tab) — remains open.
- Rendering time — Complex documents that render in seconds in native viewers can take minutes in PDF.js(opens in a new tab).
- Mobile crashes — iOS Safari enforces hard canvas memory limits (256–384 MB, depending on device). PDF.js frequently hits these limits when rendering image-heavy or high-resolution documents, causing tab crashes without warning.
- Limited progressive loading — PDF.js supports range requests and linearized PDFs, but in practice, most documents aren’t linearized, and the viewer still blocks on parsing before rendering the first page. Users often see a blank screen or spinner while the document loads.
These problems are common with scanned documents, CAD drawings, large reports, and image-heavy PDFs.
5. You’re spending more time on PDF code than product code
A PDF viewer scoped as a two-day task can generate a dedicated bug backlog within months. Developers end up spending time on:
- Debugging canvas rendering issues across browsers
- Writing custom annotation layers that don’t quite work
- Handling PDF.js version upgrades that break existing functionality
- Building workarounds for text selection problems (dozens of open issues(opens in a new tab) on GitHub)
- Responding to user complaints about print quality
PDF.js has no license fee, but engineering time to add these features can exceed the cost of a commercial license.
The real cost of building on PDF.js
This table compares costs for teams that need more than basic viewing.
| Cost category | PDF.js | Commercial SDK |
|---|---|---|
| License | Free | Annual subscription |
| Basic viewing setup | Hours | Hours |
| Annotations (15+ types) | 3–6 months of development | Included |
| Form handling | 1–3 months | Included |
| Digital signatures | 2–4 months | Included |
| Real-time collaboration | 4–8 months | Included |
| Security and encryption | 2–3 months | Included |
| Ongoing maintenance | Continuous (updates, bugs, browser compatibility) | Vendor-managed |
| Support | Community forums, no SLA | Dedicated team with SLA |
Teams that need more than two features beyond viewing will spend more on custom development than on a commercial license.
What to look for in a commercial PDF SDK
Use these criteria when evaluating commercial PDF SDKs.
- Rendering fidelity — Does it render the same as Adobe Acrobat? Test with your actual documents, not demos. See our side-by-side PDF.js vs. Nutrient comparison for specifics.
- Feature completeness — Does it include the features you need today and the ones you’ll need in 12 months?
- Framework support — Does it integrate with your stack (React, Angular, Vue, and vanilla JS)?
- Deployment flexibility — Can you run it client-side only, or does it require a server? Can you choose?
- Performance at scale — Test with your largest, most complex documents. Ask for benchmark data.
- Compliance and accessibility — Does it support PDF/A, PDF/UA, WCAG, and Section 508?
- Support and SLAs — What are the guaranteed response times? Can you talk to engineers?
- Documentation quality — Are there working code examples for your exact use case?
Nutrient Web SDK: A commercial PDF.js alternative
Nutrient Web SDK addresses each limitation described above.
Rendering
Nutrient uses a hybrid rendering architecture. Simple pages render client-side using WebAssembly. Complex or large documents offload rendering to server-side components that return prerendered pages. Colors, barcodes, and print output match Adobe Acrobat rendering.
Features
Features that require custom development with PDF.js are included:
- 15+ annotation types with XFDF and JSON import/export
- Interactive forms with JavaScript validation
- Electronic and digital signatures (PKCS#7)
- Real-time collaboration with Instant synchronization
- Page manipulation (reorder, merge, split, crop, rotate)
- Redaction with audit-safe permanent removal
- Measurement tools for technical documents
- Content editing for modifying text and images in place
- Document conversion between PDF, Office, and image formats
- Office file viewing (Word, Excel, PowerPoint) without server-side conversion
- Document Authoring for editing DOCX files in the browser
- AI Assistant for document summarization, translation, smart redaction, and semantic search
- OCR for extracting searchable text from scanned PDFs (21+ languages)
- Document comparison for detecting differences between PDF versions
- Accessibility compliance (WCAG 2.2 AA, PDF/UA, Section 508)
Try it with your own documents:
Security
Nutrient provides built-in security: AES-256 encryption, granular permission controls, DRM, and audit logging. These features meet requirements for handling legal, medical, and financial documents under HIPAA, SOC 2, and similar frameworks.
Performance
The hybrid architecture reduces browser memory pressure for large documents. Server-side rendering offloads heavy processing from the client. Progressive loading displays pages as they render.
Support
Licensing includes technical support with SLAs, engineering team access, and backward-compatible updates.
Developer experience
Nutrient Web SDK includes guides with TypeScript support and prebuilt integrations for React, Angular, and Vue.js. The following code initializes a viewer in 15 lines:
<!DOCTYPE html><html> <head> <script src="https://cdn.cloud.nutrient.io/pspdfkit-web@1.12.0/nutrient-viewer.js"></script> </head> <body> <div id="nutrient" style="width: 100%; height: 100vh;"></div> <script> NutrientViewer.load({ container: "#nutrient", document: "document.pdf", }) .then((instance) => { console.log("Nutrient loaded", instance); }) .catch((error) => { console.error(error.message); }); </script> </body></html>This initialization includes annotation, form, signature, and search support.
Migrating from PDF.js
Migrating from PDF.js to Nutrient involves:
- Replacing the viewer initialization — Swap
pdfjsLib.getDocument()withNutrientViewer.load(). - Removing custom code — Delete custom annotation layers, form handlers, and rendering workarounds that Nutrient handles natively.
- Updating event handlers — Map your existing PDF.js event listeners to Nutrient’s API.
- Testing with your documents — Verify rendering fidelity with the documents your users actually work with.
For a detailed walkthrough, see our migration guide. You can also try the Nutrient demo with your own documents to see the difference before committing to a migration.
FAQ
For read-only viewing of simple PDFs with low traffic, yes. For applications that need annotations, forms, signatures, security, or high-fidelity rendering, you need a commercial SDK. The deciding factor is whether engineering time to extend PDF.js exceeds the cost of a commercial license.
Adding a full annotation system (15+ types with import/export) takes three to six months of development. Digital signatures add two to four months. Real-time collaboration adds four to eight months. These estimates don’t include ongoing maintenance, browser compatibility testing, or bug fixes. Teams that need more than two features beyond viewing will spend less on a commercial SDK than on custom development.
Yes. Some teams use PDF.js for basic viewing in low-stakes parts of their application and a commercial SDK for document workflows that require advanced features. However, maintaining two PDF libraries adds complexity, so most teams eventually consolidate to one.
One to three days for basic viewing. If you have extensive custom code built on top of PDF.js (custom annotation layers, form handlers, rendering workarounds), the migration takes longer, but most custom PDF code can be removed. See our migration guide for step-by-step instructions.
Yes. Nutrient provides prebuilt integrations and guides for React, Angular, Vue.js, and other frameworks. The SDK also works with vanilla JavaScript and TypeScript. Setup guides are available for each framework.
PDF.js has had security vulnerabilities, including CVE-2024-4367(opens in a new tab), which allowed arbitrary JavaScript execution through malformed font data. The Mozilla team patches vulnerabilities when they’re reported, but there’s no guaranteed response time or SLA. Commercial SDKs provide dedicated security teams, coordinated disclosure, and rapid patch cycles — which matters for applications handling sensitive documents.
Related reading
- PDF.js vs. Nutrient: Feature-by-feature comparison
- Complete guide to PDF.js
- Evaluating the render fidelity of PDF.js
Try Nutrient Web SDK with a free trial, or talk to our Sales team about your requirements. For a detailed feature-by-feature breakdown, see the PDF.js vs. Nutrient SDK comparison.