PDFMacroPDFMacro
For IT and compliance reviewers

Security & Architecture

This page answers the questions law firm IT departments and compliance officers ask before approving a new document tool. Every claim below is true to the actual implementation and can be verified in the browser.

Processing model

Everything happens in the browser runtime.

When you open a PDF in PDFMacro, the file is read into browser memory as aUint8Arrayvia the standard File API. From that moment until you export, the document never exists outside the browser's execution sandbox.

Parsing, rendering, redaction, Bates stamping, OCR, and export are all performed by client-side libraries (PDF.js, pdf-lib, Tesseract.js) running inside the browser tab or its Web Workers. There is no remote processing layer, no cloud conversion API, and no server-side render path that touches document bytes.

No server receives document content

PDFMacro is deployed as a static site. There is no /upload, /process, or /convert endpoint. The server serves HTML, JavaScript, and WASM bundles only.

No remote API calls with file data

We do not call Google Cloud Vision, AWS Textract, Azure Document Intelligence, or any third-party analysis service. OCR runs on-device via Tesseract.js.

WebAssembly runs locally

WASM modules for PDF manipulation and text extraction are fetched as static assets and executed inside the browser's sandboxed WASM runtime.

No telemetry carrying document content

Error reporting and analytics contain page URLs and exception messages. They never contain filenames, extracted text, page images, or document metadata.

Local file handling

Loaded into memory. Processed locally. Stored on your device.

01

Read into browser memory

When a user selects a file, the browser's File API yields an ArrayBuffer that is wrapped in a Uint8Array. This lives in the tab's JavaScript heap — not on disk, not on a server.

02

Parsed by client-side libraries & Web Workers

PDF.js parses the byte stream inside a dedicated Web Worker so the UI thread stays responsive, even on large discovery sets. pdf-lib handles structural modifications like redaction, Bates stamping, and merging.

03

Persisted in sandboxed local storage

Recent documents, annotation sidecars, and OCR layers are stored in the browser's IndexedDB — a sandboxed, origin-scoped database on the user's own device. Data is never transmitted to remote storage.

What is persisted and where

PDFMacro maintains two IndexedDB databases on the device:pdfmacro-workspacestores UI state, recent document bytes (capped at 120 MB total), per-document annotation sidecars, and user bookmarks; andpdfmacro-custom-fontsstores fonts you upload for the editor, keyed by SHA-256. Standalone tools like Merge, Compress, and Organize keep files in page memory only — nothing they touch is written to storage. All storage is scoped to the browser origin and subject to the browser's standard security model.

Code illustration — local-only file handling

The actual code path.

The snippets below are simplified from the production codebase. They show the real flow: file bytes enter browser memory, are parsed in a Web Worker, and are stored locally in IndexedDB. At no point is a network request made with document content.

File bytes are read into memory, parsed inside a Web Worker, and persisted to IndexedDB — all on this device. At no point is a network request made with document content.THIS DEVICEFile bytesread into memoryWeb WorkerparsedIndexedDBpersistedAt no point is a network requestmade with document content.
1. File bytes are read into memory — never uploadedtypescript
// When a user drops or selects a file:
const bytes = new Uint8Array(await file.arrayBuffer());

// 'bytes' lives in the browser's JS heap only.
// There is no fetch(), no XMLHttpRequest, no FormData.
// The file never leaves the device.
2. PDF is parsed inside a Web Workertypescript
// PDF.js runs in a dedicated worker so the UI stays responsive.
const pdfjs = await loadPdfjs();
const doc = await pdfjs.getDocument({ data: bytes }).promise;

// Rendering, text extraction, and page analysis all happen
// inside the browser sandbox — no server is contacted.
3. Recent documents and edits persist to IndexedDBtypescript
// Documents are stored in the browser's origin-scoped IndexedDB.
const conn = await openDB("pdfmacro-workspace", 3, {
  upgrade(d) {
    d.createObjectStore("docs");   // recent file bytes
    d.createObjectStore("sidecars"); // annotations, page ops, OCR layer
  },
});

// Sidecars are keyed by file identity so reopening restores edits.
await conn.put("sidecars", sidecarRecord, `${fileName}::${fileSize}`);
4. Export rebuilds the PDF entirely on-devicetypescript
// pdf-lib modifies the original bytes locally and produces a new blob.
const pdfDoc = await PDFDocument.load(bytes, { ignoreEncryption: true });
// ... apply redactions, Bates stamps, rotations, merges ...
const output = await pdfDoc.save();
const blob = new Blob([output], { type: "application/pdf" });

// The user downloads via the browser's native save mechanism.
// Still no network request carrying PDF data.
Offline operation
Works without a network connection

Disconnect and continue working.

PDFMacro registers a Service Worker that precaches the application shell and stores static assets (JavaScript bundles, WASM modules, fonts, and stylesheets) at install time. Once the app has loaded, every tool functions without an internet connection because the workflow has no server dependency. This is not a fallback mode — it is the natural consequence of a fully client-side architecture.

The Service Worker also caches third-party runtime dependencies required for offline OCR (Tesseract.js core, worker scripts, and language packs) so that making a scanned PDF searchable works while air-gapped.

Air-gapped workflow

Suitable for sensitive environments.

Because no step requires a network round-trip, PDFMacro can be used on machines that are physically disconnected from the internet or confined to isolated network segments. Load the application once, then move the machine offline. Document processing, redaction, Bates stamping, and export continue to operate normally.

For firms with strict network policies, the app can be reviewed by standard browser DevTools. The Network tab will show only static asset loads on first visit; after that, all subsequent work generates zero document-bearing traffic.

Data handling statement

What we store, what we do not store, and what we transmit.

What is stored

  • Document bytes in the browser's IndexedDB, capped at 120 MB total per origin, retained only until the user clears recents or the browser evicts storage.
  • Annotation sidecars (redaction marks, page rotations, OCR text layers) keyed by file identity so edits survive a tab close and reopen.
  • UI preferences (zoom level, theme, panel state) in localStorage for convenience.

What is NOT stored or transmitted

  • Nothing is uploaded to our servers. There is no cloud storage bucket, no processing queue, and no temporary remote cache. We cannot access your documents.
  • No document content in telemetry. Analytics and error reports contain generic events (page views, uncaught exceptions). They never include filenames, extracted text, or page bitmaps.
  • No remote AI analysis. Privilege scanning and search operate on locally extracted text. We do not send document content to OpenAI, Google, or any other remote model provider.
  • On-device inference. The AI is not absent, it is local. Named-entity recognition (bert-base-NER) and sentence embeddings (all-MiniLM-L6-v2) execute in the browser tab via WebAssembly or WebGPU. Weights are fetched once from a public model host and cached on the device; inference never touches the network, so these features keep working with outbound traffic blocked.
Plain-language summary for legal teams

PDFMacro does not collect, process, or store your documents on our infrastructure. Your files remain on your device, inside your browser, under your control. We have no technical ability to view, retain, or disclose your documents because we never receive them. This architecture eliminates the data-breach and subpoena-risk vectors that come with cloud-based document tools.

Verify every claim yourself.

Open the Network tab, load a document, and watch the traffic. You will see zero outgoing requests carrying your file.