Add Annotations to Scanned PDFs in JavaScript with Dynamsoft Document Viewer
Dynamsoft Document Viewer is an SDK providing a set of viewers for document images. It has added an annotation feature since v2.0, which makes it easy to create a document scanning solution along with the following SDKs:
- Dynamic Web TWAIN to access document scanners in the browser.
- Dynamsoft Document Normalizer to detect the document boundaries.
In this article, we are going to talk about what annotations it provides, what use cases it can do and some codes for illustration.
Online demo with document scanning and annotation features
What you’ll build: A JavaScript web app that scans documents and annotates them with shapes, text, stamps, ink drawings, and redaction — then saves or reloads the annotated PDF using Dynamsoft Document Viewer.
Key Takeaways
- Dynamsoft Document Viewer v2.0+ supports rectangle, ellipse, polygon, polyline, line, text, ink, and stamp annotations on scanned document images in the browser.
- Annotations can be saved as native PDF annotations (editable in Adobe Acrobat or other viewers), flattened into page content, or merged as image data.
- You can add annotations programmatically via JavaScript — useful for automated redaction with OCR bounding boxes or batch stamping for document status tracking.
- The SDK works alongside Dynamic Web TWAIN for scanner access and Dynamsoft Document Normalizer for automatic document boundary detection.
Common Developer Questions
- How do I add annotations to a scanned PDF in JavaScript?
- Can I save PDF annotations so they stay editable in Adobe Acrobat?
- How do I programmatically redact text in a scanned document using JavaScript?
Supported Annotation Types
Currently, it can annotate with shapes, free drawing, text and images.
Shapes:
- Rectangle
- Ellipse
- Polygon
- Polyline
- Line
Text:
- TextBox
- TextTypewriter
Other:
- Ink (freehand drawing)
- Stamp (custom image)
Real-World Use Cases for PDF Annotations
Using the annotation feature, we can achieve some common tasks in document management.
-
Add comments and highlights.

-
Add barcodes or QR codes for document identification.

-
Redact sensitive information like the contact’s name or photo.

-
Proofread a manuscript by drawing markups.

-
Add stamps for specifying the document’s status.

Build a JavaScript PDF Annotator Step by Step
Let’s check out some codes to add annotations.
Step 1: Add Dynamsoft Document Viewer to Your Page
To use Dynamsoft Document Viewer in a web page, include the following files:
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.css">
Then initialize it with the following code:
Dynamsoft.DDV.Core.license = "LICENSE-KEY"; // Public trial license which is valid for 24 hours
Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/engine";// Lead to a folder containing the distributed WASM files
await Dynamsoft.DDV.Core.loadWasm();
await Dynamsoft.DDV.Core.init();
Get a 30-day free trial license for Dynamsoft Document Viewer.
Step 2: Create an Edit Viewer for Document Annotation
We need to create an instance of Edit Viewer to view and add annotations.
const editViewerUiConfig = {
type: Dynamsoft.DDV.Elements.Layout,
flexDirection: "column",
className: "ddv-edit-viewer-mobile",
children: [
{
type: Dynamsoft.DDV.Elements.Layout,
className: "ddv-edit-viewer-header-mobile",
children: [
Dynamsoft.DDV.Elements.Pagination,
{
type: Dynamsoft.DDV.Elements.Button,
className: "ddv-button-done",
events:{
click: "close"
}
}
],
},
Dynamsoft.DDV.Elements.MainView,
{
type: Dynamsoft.DDV.Elements.Layout,
className: "ddv-edit-viewer-footer-mobile",
children: [
Dynamsoft.DDV.Elements.DisplayMode,
Dynamsoft.DDV.Elements.RotateLeft,
Dynamsoft.DDV.Elements.Crop,
Dynamsoft.DDV.Elements.Filter,
Dynamsoft.DDV.Elements.Undo,
Dynamsoft.DDV.Elements.Delete,
Dynamsoft.DDV.Elements.AnnotationSet
],
},
],
};
// Create an edit viewer
editViewer = new Dynamsoft.DDV.EditViewer({
container: "fullscreenContainer",
groupUid: captureViewer.groupUid,
uiConfig: editViewerUiConfig
});
// Configure image filter feature which is in edit viewer
Dynamsoft.DDV.setProcessingHandler("imageFilter", new Dynamsoft.DDV.ImageFilter());
Open the Edit Viewer, click the annotation icon and we can start adding annotations via the UI.

Step 3: Add Annotations Programmatically
Apart from using the Edit Viewer, we can also add annotations via code.
For example, we need to redact some words like names. We can use OCR to get the bounding boxes of the words and add rectangle annotations accordingly. Please note that the coordinates should be in point and we need to convert pixels to points first.
const pageUid = editViewer.indexToUid(pageIndex);
const pageData = await doc.getPageData(pageUid);
const scaleX = pageData.mediaBox.width / pageData.raw.width; //for converting pixels to points
const scaleY = pageData.mediaBox.height / pageData.raw.height;
const options = {
x: bbox.x0*scaleX,
y: bbox.y0*scaleY,
width: (bbox.x1 - bbox.x0)*scaleX,
height: (bbox.y1 - bbox.y0)*scaleY,
borderColor: "black",
background: "black"
//flags:{readOnly:true} //enable read only if you do not need to interact with the annotation
}
const rect = Dynamsoft.DDV.annotationManager.createAnnotation(pageUid, "rectangle",options);
You can add other types of annotations. Check out the docs for details.
Step 4: Save Annotated Documents as PDF
We can save the images as a PDF file with annotations.
const pdfSettings = {
saveAnnotation: "annotation"
};
const blob = await doc.saveToPdf(pdfSettings);
We can specify how to save the annotations using the saveAnnotation setting. It has the following options:
none: not saving annotations.image: saving annotations as a part of image.annotation: saving annotations as pdf annotations.flatten: saving annotations as page content.
If we choose the annotation option, we can continue editing the annotations later using Dynamsoft Document Viewer or other PDF editors like Adobe Acrobat.
Step 5: Load and Edit Existing PDF Annotations
If we have an existing PDF file with annotations, we can load it with the following code:
let pdfSource = {
fileData:blob,
renderOptions:{
renderAnnotations:Dynamsoft.DDV.EnumAnnotationRenderMode.LOAD_ANNOTATIONS
}
}
await doc.loadSource(pdfSource);
There are several modes for loading the annotations:
enum EnumAnnotationRenderMode {
NO_ANNOTATIONS = "noAnnotations", // default, means that the annotations in the PDF file will not be loaded
RENDER_ANNOTATIONS = "renderAnnotations", // means that the annotations in the PDF file will be rendered
LOAD_ANNOTATIONS = "loadAnnotations", // means that the annotations in the PDF file will be loaded normally, a valid PDF Annotation license is requested
}
If we choose the LOAD_ANNOTATIONS mode, we can continue editing the existing annotations in a PDF file.
Common Issues and Edge Cases
- Coordinate mismatch when adding annotations programmatically: The annotation API uses point units, not pixels. Always convert pixel coordinates from OCR or image processing output using the
mediaBoxdimensions — failing to scale will place annotations in the wrong position. - Annotations not visible after saving and reopening: Make sure the
saveAnnotationoption is set to"annotation"or"flatten". The default"none"discards all annotations on save. - LOAD_ANNOTATIONS mode requires a valid PDF Annotation license: If you load a PDF with
RENDER_ANNOTATIONS, annotations are baked into the image and cannot be edited. UseLOAD_ANNOTATIONSonly when you have the correct license key to enable full round-trip editing.
Source Code
Check out the source code of the demo to have a try.
https://github.com/tony-xlh/document-viewer-samples/tree/main/scan-and-annotate