PDF.js limitations: When to upgrade to a commercial PDF SDK

Table of contents

    PDF.js limitations: When to upgrade to a commercial PDF SDK
    TL;DR

    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.

    FeaturePDF.jsCustom build required?
    Render and view PDFsYesNo
    Text searchYesNo
    Highlight, ink, stamp, free text, signature annotationsYes (five types)No
    Shape annotations (arrows, circles, lines)NoYes
    Sticky notes and commentsNoYes
    Annotation import/export (XFDF)NoYes
    Interactive form fillingPartialYes, for validation and submission
    Form creationNoYes
    Electronic signaturesPartialYes, for workflows and verification
    Digital signatures (PKCS#7)NoYes
    Page manipulation (reorder, merge, split)NoYes
    RedactionNoYes
    Real-time collaborationNoYes
    Measurement toolsNoYes
    Office file viewing (Word, Excel, PowerPoint)NoYes
    OCR (text extraction from scanned PDFs)NoYes
    Document comparisonNoYes
    AI-powered document processingNoYes
    WCAG 2.2 AA accessibilityPartialYes, 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 categoryPDF.jsCommercial SDK
    LicenseFreeAnnual subscription
    Basic viewing setupHoursHours
    Annotations (15+ types)3–6 months of developmentIncluded
    Form handling1–3 monthsIncluded
    Digital signatures2–4 monthsIncluded
    Real-time collaboration4–8 monthsIncluded
    Security and encryption2–3 monthsIncluded
    Ongoing maintenanceContinuous (updates, bugs, browser compatibility)Vendor-managed
    SupportCommunity forums, no SLADedicated 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:

    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:

    1. Replacing the viewer initialization — Swap pdfjsLib.getDocument() with NutrientViewer.load().
    2. Removing custom code — Delete custom annotation layers, form handlers, and rendering workarounds that Nutrient handles natively.
    3. Updating event handlers — Map your existing PDF.js event listeners to Nutrient’s API.
    4. 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

    Is PDF.js good enough for production applications?

    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.

    How much does it cost to build PDF.js features from scratch?

    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.

    Can I use PDF.js and a commercial SDK together?

    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.

    How long does it take to migrate from PDF.js to Nutrient?

    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.

    Does Nutrient Web SDK work with React, Angular, and Vue?

    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.

    What about PDF.js security vulnerabilities?

    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.


    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.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    Try for free Ready to get started?