---
title: "How to make PDFs fillable"
canonical_url: "https://www.nutrient.io/blog/fillable-pdf/"
md_url: "https://www.nutrient.io/blog/fillable-pdf.md"
last_updated: "2026-08-21T21:30:38.865Z"
description: "Learn how to make PDFs fillable with this comprehensive guide. Explore various tools and methods, from free software to advanced solutions with Nutrient (formerly PSPDFKit)."
---

Fillable PDFs reduce data entry errors, speed up document processing, and support remote collaboration. If you’re creating forms, contracts, or surveys, choosing the right [PDF form builder](https://www.nutrient.io/sdk/solutions/forms/) saves significant development time.

**TL;DR**

This guide covers three approaches to creating fillable PDFs: PDF.js for viewing and filling existing forms, pdf-lib for programmatic PDF manipulation, and Nutrient Web SDK for complete form solutions with built-in UI, validation, and eSignatures.

## 1. How to make PDFs fillable using open source libraries

To make PDFs fillable, you need software capable of defining interactive fields within a document. Several open source libraries can handle this task, each with different capabilities and limitations.

### PDF.js

[PDF.js](https://mozilla.github.io/pdf.js/) is a popular library developed by Mozilla for rendering PDF documents in web browsers. It natively supports displaying and filling existing PDF forms. If your PDF already has form fields, PDF.js will render them and allow users to fill them out directly in the browser.

However, PDF.js cannot programmatically create new form fields on a PDF that doesn’t already have them. While you could manually overlay HTML input fields on the canvas, this approach is complex and the data entered doesn’t actually become part of the PDF — it’s just floating on top of the rendered image.

PDF.js works well for displaying and filling existing PDF forms. However, creating new form fields requires extensive custom JavaScript, CSS positioning, and event handling. The user experience with custom overlays often feels disconnected from the PDF itself.

### pdf-lib

[`pdf-lib`](https://pdf-lib.js.org/) is a versatile library for creating and modifying PDF documents, and it works seamlessly in both Node.js and browser environments.

**Step 1 — Installing pdf-lib**

If you’re using Node.js, install pdf-lib via npm:

```bash

npm install pdf-lib

```

**Step 2 — Listing available form fields**

First, find out what fields exist in your PDF. Save this file with an `.mjs` extension (e.g. `listFields.mjs`):

```javascript

import { PDFDocument } from "pdf-lib";
import fs from "fs";

async function listFields() {
  const existingPdfBytes = fs.readFileSync("sample_pdf.pdf");
  const pdfDoc = await PDFDocument.load(existingPdfBytes);
  const form = pdfDoc.getForm();
  const fields = form.getFields();

  console.log("Available form fields:");
  fields.forEach((field) => {
    const name = field.getName();
    const type = field.constructor.name;
    console.log(`- ${name} (${type})`);
  });
}

listFields();

```

Run with: `node listFields.mjs`

**Step 3 — Filling form fields**

Once you know the field names, use the appropriate method based on the field type:

```javascript

import { PDFDocument } from "pdf-lib";
import fs from "fs";

async function fillPdf() {
  const existingPdfBytes = fs.readFileSync("sample_pdf.pdf");
  const pdfDoc = await PDFDocument.load(existingPdfBytes);
  const form = pdfDoc.getForm();

  // For `PDFTextField` — use the exact field name from Step 2.
  const textField = form.getTextField("TEXT_FIELD_NAME");
  textField.setText("Your value here");

  // For `PDFCheckBox`.
  const checkbox = form.getCheckBox("CHECKBOX_FIELD_NAME");
  checkbox.check(); // Or `checkbox.uncheck()`.

  // For `PDFRadioGroup`.
  const radioGroup = form.getRadioGroup("RADIO_FIELD_NAME");
  radioGroup.select("option1"); // Select one of the radio options.

  // For `PDFDropdown`.
  const dropdown = form.getDropdown("DROPDOWN_FIELD_NAME");
  dropdown.select("optionValue");

  const pdfBytes = await pdfDoc.save();
  fs.writeFileSync("filled.pdf", pdfBytes);
}

fillPdf();

```

Run with: `node fillPdf.mjs`

Use only the methods that match your PDF’s field types. `PDFButton` fields are typically for actions, not data entry.

pdf-lib works for developers comfortable writing custom code, but you’ll need to build field focus management, error handling, validation, and data extraction yourself. There are no built-in user interface (UI) components.

## 2. How to make PDFs fillable with advanced features using Nutrient

[Nutrient Web SDK](https://www.nutrient.io/guides/web/forms.md) provides a JavaScript library for generating, customizing, and managing PDF forms programmatically. This section covers how to create various form fields and customize them.

[Explore the Nutrient demo](https://www.nutrient.io/demo)

### Prerequisites

You need a valid Nutrient license with Form Creator support (version 2019.5 or newer) for creating form fields. For adding form fields using the UI, you’ll need version 2022.3 or later.

**Step 1 — Installation**

Choose either CDN or npm installation.

**Option A: CDN (quickest)**

```html

<!DOCTYPE html>
<html>
  <head>
    <title>Nutrient Web SDK</title>
  </head>
  <body>
    <script src="https://cdn.cloud.nutrient.io/pspdfkit-web@1.20.0/nutrient-viewer.js"></script>
    <div id="pdf-viewer" style="width: 100%; height: 100vh;"></div>
    <script src="index.js"></script>
  </body>
</html>

```

**Option B: npm package**

```bash

npm install @nutrient-sdk/viewer

```

**Step 2 — Loading Nutrient**

Initialize Nutrient Web SDK and load a PDF:

```javascript

const container = document.getElementById("pdf-viewer");

// For CDN installation.
const { NutrientViewer } = window;

// For npm installation, import at the top of your file:
// import NutrientViewer from "@nutrient-sdk/viewer";

if (container && NutrientViewer) {
  NutrientViewer.load({
    container,
    document: "document.pdf",
  }).then((instance) => {
      console.log("Nutrient loaded", instance);
    }).catch((error) => {
      console.error(error.message);
    });
}

```

**Step 3 — Creating a text form field**

Use `NutrientViewer.Annotations.WidgetAnnotation` for the widget and `NutrientViewer.FormFields.TextFormField` for the form field:

```javascript

const widget = new NutrientViewer.Annotations.WidgetAnnotation({
  id: NutrientViewer.generateInstantId(),
  pageIndex: 0,
  formFieldName: "MyFormField",
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 100,
    top: 75,
    width: 200,
    height: 80,
  }),
});

const textFormField = new NutrientViewer.FormFields.TextFormField({
  name: "MyFormField",
  annotationIds: new NutrientViewer.Immutable.List([widget.id]),
  value: "Text shown in the form field",
});

instance.create([widget, textFormField]);

```

**Step 4 — Creating radio buttons**

Create multiple widgets with the same form field name:

```javascript

const radioWidget1 = new NutrientViewer.Annotations.WidgetAnnotation({
  id: NutrientViewer.generateInstantId(),
  pageIndex: 0,
  formFieldName: "MyRadioField",
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 100,
    top: 170,
    width: 20,
    height: 20,
  }),
});

const radioWidget2 = new NutrientViewer.Annotations.WidgetAnnotation({
  id: NutrientViewer.generateInstantId(),
  pageIndex: 0,
  formFieldName: "MyRadioField",
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 130,
    top: 170,
    width: 20,
    height: 20,
  }),
});

const radioFormField = new NutrientViewer.FormFields.RadioButtonFormField({
  name: "MyRadioField",
  annotationIds: new NutrientViewer.Immutable.List([
    radioWidget1.id,
    radioWidget2.id,
  ]),
  options: new NutrientViewer.Immutable.List([
    new NutrientViewer.FormOption({
      label: "Option 1",
      value: "1",
    }),
    new NutrientViewer.FormOption({
      label: "Option 2",
      value: "2",
    }),
  ]),
  defaultValue: "1",
});

instance.create([radioWidget1, radioWidget2, radioFormField]);

```

**Step 5 — Enable form design mode**

Allow users to adjust the placement of form elements:

```javascript

instance.setViewState((viewState) => viewState.set("formDesignMode", true));

```

Here’s the full code combining all steps:

```js

const container = document.getElementById("pdf-viewer");
const { NutrientViewer } = window; // For CDN installation

if (container && NutrientViewer) {
  NutrientViewer.load({
    container,
    document: "document.pdf",
  }).then((instance) => {
      console.log("Nutrient loaded", instance);

      // Create a text form field.
      const widget = new NutrientViewer.Annotations.WidgetAnnotation({
        id: NutrientViewer.generateInstantId(),
        pageIndex: 0,
        formFieldName: "MyFormField",
        boundingBox: new NutrientViewer.Geometry.Rect({
          left: 100,
          top: 75,
          width: 200,
          height: 80,
        }),
      });

      const textFormField = new NutrientViewer.FormFields.TextFormField({
        name: "MyFormField",
        annotationIds: new NutrientViewer.Immutable.List([widget.id]),
        value: "Text shown in the form field",
      });

      instance.create([widget, textFormField]);

      // Create radio button form field with two options.
      const radioWidget1 = new NutrientViewer.Annotations.WidgetAnnotation({
        id: NutrientViewer.generateInstantId(),
        pageIndex: 0,
        formFieldName: "MyRadioField",
        boundingBox: new NutrientViewer.Geometry.Rect({
          left: 100,
          top: 170,
          width: 20,
          height: 20,
        }),
      });

      const radioWidget2 = new NutrientViewer.Annotations.WidgetAnnotation({
        id: NutrientViewer.generateInstantId(),
        pageIndex: 0,
        formFieldName: "MyRadioField",
        boundingBox: new NutrientViewer.Geometry.Rect({
          left: 130,
          top: 170,
          width: 20,
          height: 20,
        }),
      });

      const radioFormField = new NutrientViewer.FormFields.RadioButtonFormField(
        {
          name: "MyRadioField",
          annotationIds: new NutrientViewer.Immutable.List([
            radioWidget1.id,
            radioWidget2.id,
          ]),
          options: new NutrientViewer.Immutable.List([
            new NutrientViewer.FormOption({
              label: "Option 1",
              value: "1",
            }),
            new NutrientViewer.FormOption({
              label: "Option 2",
              value: "2",
            }),
          ]),
          defaultValue: "1",
        },
      );

      instance.create([radioWidget1, radioWidget2, radioFormField]);

      // Enable form design mode.
      instance.setViewState((viewState) =>
        viewState.set("formDesignMode", true),
      );
    }).catch((error) => {
      console.error("Error loading Nutrient:", error.message);
    });
}

```

## Comparison of fillable PDF creation tools

| Feature                    | PDF.js                 | pdf-lib                   | Nutrient Web SDK        |
| -------------------------- | ---------------------- | ------------------------- | ----------------------- |
| **Fill existing forms**    | ✓                      | ✓                         | ✓                       |
| **Create new form fields** | Manual overlay only    | ✓                         | ✓                       |
| **Built-in UI**            | ✗                      | ✗                         | ✓                       |
| **Form validation**        | Custom                 | Custom                    | Built-in                |
| **eSignatures**            | ✗                      | ✗                         | ✓                       |
| **Data extraction**        | Custom                 | Custom                    | Built-in                |
| **Mobile support**         | Basic                  | Basic                     | Optimized               |
| **Best for**               | Viewing existing forms | Programmatic manipulation | Production applications |

## Best practices to make PDFs fillable

1. Use a clear and consistent layout — Organized layouts make forms easy to read and navigate.

2. Use clear and concise language — Form labels and instructions should be straightforward.

3. Use headings and subheadings — Organize forms with headings for easy scanning.

4. Use bullet points and numbered lists — These elements improve readability.

5. Ensure form fields are large enough — Fields should be sized appropriately for comfortable data entry.

6. Clearly label the submit button — Make submission buttons easy to find with clear labels.

7. Test your form — Verify forms work correctly and users can complete and submit them.

## Conclusion

Free libraries like PDF.js and pdf-lib work well for simple use cases and prototypes. For production applications requiring form creation, validation, eSignatures, and a complete user interface, Nutrient Web SDK provides these capabilities out of the box.

[Try Nutrient’s demo](https://www.nutrient.io/demo/) to explore the available features, or [contact our Sales team](https://www.nutrient.io/contact-sales?=sdk) to discuss your specific requirements.

## Related reading

- [Create and fill PDF forms programmatically in JavaScript](https://www.nutrient.io/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md) — A deeper code walkthrough of JavaScript form fields

- [Create a PDF form with a signature](https://www.nutrient.io/blog/creating-a-pdf-form-with-signature/) — Add signature fields to a fillable form

- [The complete guide to digital signatures](https://www.nutrient.io/blog/complete-guide-digital-signatures/) — eSignature and digital signature options for forms

## FAQ

#### What are fillable PDFs?

Fillable PDFs are documents that allow users to enter information directly into designated fields, making data entry easier and more efficient.

#### Why should I use fillable PDFs instead of traditional forms?

Fillable PDFs enable easy data capture and sharing, reducing the challenges of paper-based forms.

#### What tools can I use to create fillable PDFs?

You can create fillable PDFs using various tools, including open source libraries like `pdf-lib`, or commercial solutions like Nutrient (formerly PSPDFKit).

#### Can I create fillable PDFs using JavaScript?

Yes. You can create fillable PDFs using JavaScript libraries such as `pdf-lib` and Nutrient, which provide functionality for adding interactive form fields.

#### Are there any limitations to creating fillable PDFs?

Some libraries may have limitations in terms of features or ease of use, requiring custom coding for field management or a deeper understanding of PDF structures for advanced functionalities.
---

## 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)
- [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)
- [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 Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [Build Vs Buy Document Extraction](/blog/build-vs-buy-document-extraction.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)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.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)
- [How To Build A Javascript Pdf Viewer](/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 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)
- [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)
- [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)
- [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 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)
- [Building WCAG 2.2, Section 508, and PDF/UA-compliant PDFs 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)
- [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)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [React Pdf Loading States Errors Passwords](/blog/react-pdf-loading-states-errors-passwords.md)
- [React Pdf Setup Basic Rendering](/blog/react-pdf-setup-basic-rendering.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)
- [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)
- [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 Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-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)

