---
title: "react-pdf performance: Memoization, virtualization, DPI"
canonical_url: "https://www.nutrient.io/blog/react-pdf-performance-optimization/"
md_url: "https://www.nutrient.io/blog/react-pdf-performance-optimization.md"
last_updated: "2026-09-11T15:53:06.497Z"
description: "Optimize react-pdf performance: memoize props, cap device pixel ratio, virtualize pages, disable unused layers, and configure range requests."
---

**TL;DR**

- Memoize the `file` and `options` props — both compare with `===`, so a fresh object on every render triggers a refetch loop.

- Cap `devicePixelRatio` (e.g. `Math.min(2, window.devicePixelRatio)`) — 3× rendering uses ~9× the memory of 1×.

- Render only the pages the user can see. A page window of 3 is enough for most viewers; reach for `react-window`’s `VariableSizeList` if your PDF has mixed page sizes.

- Disable unused layers (`renderTextLayer={false}`, `renderAnnotationLayer={false}`) and make sure your server returns `Accept-Ranges: bytes` so PDF.js can stream byte ranges.

`react-pdf` can consume significant memory and CPU, especially with large documents or high-dots-per-inch (DPI) displays. This guide covers the officially recommended optimization techniques.

## 1. Memoize the file prop

The most common `react-pdf` performance issue: The `file` prop uses strict equality (`===`). If you create a new object each render, the PDF refetches every time:

```tsx

// BAD — new object every render → infinite refetch loop.
function Viewer({ url }) {
  return <Document file={{ url }} />;
}

// GOOD — memoized.
function Viewer({ url }) {
  const file = useMemo(() => ({ url }), [url]);
  return <Document file={file} />;
}

// GOOD — stored in state.
function Viewer({ url }) {
  const [file] = useState(() => ({ url }));
  return <Document file={file} />;
}

// GOOD — string URL (primitives are compared by value).
function Viewer({ url }) {
  return <Document file={url} />;
}

```

## 2. Memoize the options prop

The same issue applies to `options`:

```tsx

// BAD — new object every render.
<Document options={{ cMapUrl: "/cmaps/" }} />

// GOOD — defined outside component.
const options = { cMapUrl: "/cmaps/" };

function Viewer() {
  return <Document file={file} options={options} />;
}

// GOOD — memoized inside component.
function Viewer() {
  const options = useMemo(() => ({ cMapUrl: "/cmaps/" }), []);
  return <Document file={file} options={options} />;
}

```

## 3. Cap device pixel ratio

On high-DPI displays (Retina, 2× or 3×), PDF.js renders the canvas at the same multiplier — that’s 4× or 9× the pixels, and roughly 4× or 9× the memory. Cap it:

```tsx

<Page
  pageNumber={1}
  devicePixelRatio={Math.min(2, window.devicePixelRatio)}
/>

```

For thumbnails, use an even lower `devicePixelRatio` cap:

```tsx

<Thumbnail
  pageNumber={1}
  width={150}
  devicePixelRatio={1}
/>

```

| DPI | Canvas for 800px wide page | Memory   |
| --- | -------------------------- | -------- |
| 1×  | 800 × 1035                 | ~3.3 MB  |
| 2×  | 1600 × 2070                | ~13.2 MB |
| 3×  | 2400 × 3105                | ~29.8 MB |

The memory required is `width × height × 4` bytes (RGBA, one byte per channel).

## 4. Render only visible pages

Don’t render all pages at once for large documents. Use a windowed approach:

```tsx

function VirtualizedPDF() {
  const [numPages, setNumPages] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);
  const windowSize = 3; // Render current page +/- 1.

  const visiblePages = useMemo(() => {
    if (!numPages) return [];
    const start = Math.max(1, currentPage - Math.floor(windowSize / 2));
    const end = Math.min(numPages, start + windowSize - 1);
    return Array.from({ length: end - start + 1 }, (_, i) => start + i);
  }, [currentPage, numPages, windowSize]);

  return (
    <Document
      file={file}
      onLoadSuccess={({ numPages }) => setNumPages(numPages)}
    >
      {visiblePages.map((pageNum) => (
        <Page key={pageNum} pageNumber={pageNum} />
      ))}
    </Document>
  );
}

```

For a full virtual scroll implementation, use a library like `react-window` or `react-virtualized`:

```tsx

import { FixedSizeList } from "react-window";

function VirtualScrollPDF({ numPages }) {
  return (
    <Document file={file}>
      <FixedSizeList
        height={800}
        width={600}
        itemCount={numPages}
        itemSize={1035} // Approximate page height.
      >
        {({ index, style }) => (
          <div style={style}>
            <Page pageNumber={index + 1} width={600} />
          </div>
        )}
      </FixedSizeList>
    </Document>
  );
}

```

`FixedSizeList` assumes every page is the same height. If your PDF has mixed page sizes (portrait/landscape, A4/Letter, foldouts), switch to `VariableSizeList` and compute each page’s height from the viewport returned by `<Page>`’s `onLoadSuccess` callback.

## 5. Don’t resize canvas with CSS

Never use CSS `width`/`height` or transforms to resize the canvas. This doesn’t change the rendering resolution — it just stretches the pixels, causing blurriness or wasted memory:

```tsx

// BAD — CSS resize (stretches pixels, doesn't change render resolution).
<Page pageNumber={1} />
//.react-pdf__Page canvas { width: 400px; }  ← in your stylesheet.

// GOOD — use the `width` prop.
<Page pageNumber={1} width={400} />

```

## 6. Disable unnecessary layers

If you don’t need text selection or annotations, disable them:

```tsx

<Page
  pageNumber={1}
  renderTextLayer={false}       // Skip text layer.
  renderAnnotationLayer={false} // Skip annotation layer.
/>

```

Each layer adds document object model (DOM) elements and processing time.

## 7. Use renderMode “none” for data-only

This is useful when you only need text or annotation data, not visual rendering:

```tsx

<Page
  pageNumber={1}
  renderMode="none"
  renderTextLayer={false}
  renderAnnotationLayer={false}
  onGetTextSuccess={({ items }) => {
    // Process text without rendering.
  }}
/>

```

## 8. Server-side considerations

Ensure your server supports HTTP 206 (Partial Content) for range requests. Range request support allows PDF.js to download only the needed parts of the PDF instead of the entire file:

```http

Accept-Ranges: bytes
Content-Range: bytes 0-65535/1234567

```

Without range request support, the entire PDF must download before the first page renders.

## Summary checklist

| Optimization                   | Impact   | Effort |
| ------------------------------ | -------- | ------ |
| Memoize `file` prop            | Critical | Low    |
| Memoize `options` prop         | High     | Low    |
| Cap `devicePixelRatio`         | High     | Low    |
| Virtualize pages               | High     | Medium |
| Disable unused layers          | Medium   | Low    |
| Use `width` prop not CSS       | Medium   | Low    |
| Enable range requests (server) | High     | Medium |
| Lower thumbnail DPI            | Medium   | Low    |

## How Nutrient Web SDK handles this

Every optimization technique in this guide is handled automatically by Nutrient Web SDK’s WebAssembly (WASM) rendering engine:

```js

// No memoization, no DPI capping, no virtualization, no layer toggling.
// All optimizations are automatic.
const instance = await NutrientViewer.load({
  container: "#pdf-container",

  document: "document.pdf",
  // WASM rendering engine handles:
  // - Progressive loading and render prioritization.
  // - Automatic memory management.
  // - DPI-aware rendering without canvas bloat.
  // - Only visible pages rendered.
});

```

Most of the client-side optimizations in this guide — memoizing props, capping DPI, virtualizing pages, disabling layers, managing memory — are handled automatically by Nutrient’s WASM rendering engine. Range requests still depend on your server returning `Accept-Ranges: bytes`, but Nutrient takes advantage of them automatically when available.

[Learn more about Nutrient Web SDK](https://www.nutrient.io/sdk/web-overview/) | [Migration guide](https://www.nutrient.io/guides/web/about/migration-guides/migrating-from-react-pdf.md) | [Contact Sales](https://www.nutrient.io/contact-sales/?=sdk)

## FAQ

#### Why is my PDF refetching on every render?

The `file` prop is compared by reference (`===`). If you pass an object literal like `<Document file={{ url }} />`, React sees a new object on every render and `react-pdf` reloads the document. Memoize the object with `useMemo`, lift it to state, define it outside the component, or pass a plain string URL.

#### What’s a safe <code>devicePixelRatio</code> cap?

`Math.min(2, window.devicePixelRatio)` is the common compromise — sharp on Retina, half the memory of a 3× render on phones. For thumbnails, set `devicePixelRatio={1}`. If you’re targeting strictly print-quality output, leave it at the native value and accept the memory cost.

#### How big a page window should I render?

For most viewers, the current page plus one above and one below is enough. Start at three and increase only if users see flashes of blank space when scrolling fast. Larger windows trade memory for fewer mid-scroll renders.

#### Can I use <code>react-window</code> if my PDF has different page sizes?

Yes — use `VariableSizeList` instead of `FixedSizeList`. Compute each page’s height from the viewport you get back in `<Page>`’s `onLoadSuccess` (or preload page metadata via `pdf.getPage()`). Then feed those heights into the list.

#### Does disabling the text layer break copy-paste?

Yes. The text layer is what makes the rendered page text-selectable and searchable in the DOM. Only disable it for view-only contexts (thumbnails, previews, screenshots-as-images). If you need search but not selection, keep the text layer and hide it visually instead.

#### How do I tell whether my server supports range requests?

Send a `HEAD` request and look for `Accept-Ranges: bytes` in the response. Or open the DevTools Network panel, load the PDF, and check for multiple 206 Partial Content responses with `Range:` request headers — that’s PDF.js streaming byte ranges. Some content delivery network (CDN) configurations strip `Accept-Ranges` for gzipped content; serve PDFs uncompressed (`Content-Encoding: identity`).
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [How to build an AI agent for contract redlining against a compliance playbook](/blog/ai-contract-redlining-compliance-playbook.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Amazon Textract Alternatives](/blog/amazon-textract-alternatives.md)
- [Start (clears any prior buffer), navigate the document, then stop into a file.](/blog/android-faster-pdf-rendering.md)
- [Android Pdf Out Of Memory Handling](/blog/android-pdf-out-of-memory-handling.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Approval Workflow Software](/blog/approval-workflow-software.md)
- [Approvals Matrix](/blog/approvals-matrix.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Simple PII redaction.](/blog/automated-pii-removal.md)
- [Best Ai Document Workflow Platforms](/blog/best-ai-document-workflow-platforms.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Classification Platforms](/blog/best-document-classification-platforms.md)
- [Best document parser for RAG: LlamaParse vs. Unstructured vs. Reducto vs. Nutrient](/blog/best-document-parser-llamaparse-unstructured-reducto.md)
- [Best Document Parsing Apis](/blog/best-document-parsing-apis.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [Best Multilingual Ocr Software](/blog/best-multilingual-ocr-software.md)
- [Best Secure Document Collaboration Platforms](/blog/best-secure-document-collaboration-platforms.md)
- [Bpm Guide](/blog/bpm-guide.md)
- [Bpm Tools](/blog/bpm-tools.md)
- [Build Vs Buy Document Extraction](/blog/build-vs-buy-document-extraction.md)
- [Business Automation](/blog/business-automation.md)
- [Capex Vs Opex](/blog/capex-vs-opex.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extend Alternatives](/blog/extend-alternatives.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Html To Pptx](/blog/how-to-convert-html-to-pptx.md)
- [Quarterly report](/blog/how-to-convert-pdf-to-markdown-using-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [How To Programmatically Create And Fill Pdf Form In Angular](/blog/how-to-programmatically-create-and-fill-pdf-form-in-angular.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Html To Pdf In Javascript](/blog/html-to-pdf-in-javascript.md)
- [Invoice Approval Software](/blog/invoice-approval-software.md)
- [Javascript Document Editor](/blog/javascript-document-editor.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Langextract Vs Llamaindex Extraction Comparison](/blog/langextract-vs-llamaindex-extraction-comparison.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Uses OpenAI by default — set OPENAI_API_KEY.](/blog/llamaindex-vs-langchain-rag.md)
- [Llamaparse Alternatives](/blog/llamaparse-alternatives.md)
- [Low Code No Code Document Integrations](/blog/low-code-no-code-document-integrations.md)
- [Material Requisition](/blog/material-requisition.md)
- [or](/blog/merge-pdfs.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Flutter 6 Bindings Api](/blog/nutrient-flutter-6-bindings-api.md)
- [Nutrient Flutter Bindings Architecture](/blog/nutrient-flutter-bindings-architecture.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [PDF accessibility for developers: Meeting WCAG 2.2, Section 508, and PDF/UA with an SDK](/blog/pdf-accessibility.md)
- [Extract data from PDF files: A developer guide to structured data from PDFs and scans](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdf Ua Validation](/blog/pdf-ua-validation.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [People Process Tools](/blog/people-process-tools.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [React Pdf Annotation Layer Forms](/blog/react-pdf-annotation-layer-forms.md)
- [React Pdf Custom Rendering Hooks](/blog/react-pdf-custom-rendering-hooks.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [React Pdf Loading States Errors Passwords](/blog/react-pdf-loading-states-errors-passwords.md)
- [React Pdf Outline Table Of Contents](/blog/react-pdf-outline-table-of-contents.md)
- [React Pdf Setup Basic Rendering](/blog/react-pdf-setup-basic-rendering.md)
- [React Pdf Text Layer Custom Renderer](/blog/react-pdf-text-layer-custom-renderer.md)
- [React Pdf Thumbnails Page Navigation](/blog/react-pdf-thumbnails-page-navigation.md)
- [Reducto Alternatives](/blog/reducto-alternatives.md)
- [Requisition System](/blog/requisition-system.md)
- [labels.py](/blog/route-documents-automatically-classify-api.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [System Of Record Vs Source Of Truth](/blog/system-of-record-vs-source-of-truth.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [The Six Best Pdf Generator Apis](/blog/the-six-best-pdf-generator-apis.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Business Logic](/blog/what-is-business-logic.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Ocr Invoice Processing](/blog/what-is-ocr-invoice-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

