Free and open source · v0.2.0

Show your users exactly what they need.
Hide the rest.

Free PDF SDK is a white-label PDF viewer, annotator and editor for the web. Your users switch PDF layers on and off with a click. You switch panels, tools and whole features on or off, and every menu, toolbar and shortcut follows. It runs in the browser, so documents never leave your page.

$ npm install free-pdf-sdk
Free PDF SDK with the Layers panel open: Structure, Furniture, Electrical and Dimensions layers of a floor plan, each with a show/hide toggle Free PDF SDK in the dark theme with the Layers panel open: Structure, Furniture, Electrical and Dimensions layers of a floor plan, each with a show/hide toggle
ReactNext.jsVueNuxtAngularSvelteSvelteKitWeb ComponentsVanilla JSLit
0modes, from read-only to full authoring
0feature switches, each hidden everywhere when off
0interface languages
0servers. Documents stay on the device

PDF layers

Show a layer. Hide a layer. One click.

Structure, furniture, electrical, plumbing, dimensions, revisions: CAD exports keep them on PDF layers. The Layers panel lists every layer in the drawing and switches it on or off, and the page redraws instantly. Printing follows what is shown; the file itself is untouched.

01

Every layer on

The plan opens with all four layers visible, exactly as the file was exported. Nothing is flattened, nothing is lost.

02

Hide the furniture

The client sees the shell as it will be built. Furniture layouts disappear without touching the file.

03

Check the electrical

Dimensions and furniture off: outlets, switches and lights stand out against the walls, so the electrician can check every run.

04

Dimensions for site

Structure and dimensions only: a clean setting-out drawing for the contractor, with nothing in the way.

Try it on the sample plan
LIVINGBEDROOMBATH 8 0004 6004 0004 000SCALE 1:100 · mm
Layers 4

Click a layer to toggle it

Everything a document workflow needs

A complete PDF toolkit. Only the parts you switch on.

Every capability below is a feature flag. Leave one off and it disappears from the toolbars, the menus, the right-click menus and the keyboard shortcuts.

Hide what you don't need

Pick a mode, then fine-tune with 31 feature switches. What's off is gone from every menu, not greyed out.

Measurement

Distance, perimeter and area with a drawing scale.

Comments & review

Notes, callouts, highlights, shapes, ink and stamps, with replies and review status.

Forms, Fill & Sign

Fill fields, tick boxes, add dates and drawn or typed signatures. Design forms in edit mode.

Page organization

Insert, delete, rotate, reorder, duplicate, crop, replace and number pages.

Private by design

WebAssembly in an iframe on your own origin. No server, no uploads, no tracking. AES-256 encrypted files open in place, and an owner password lifts their restrictions.

Redaction

Mark, apply and sanitize. Hidden information is removed, not covered.

Signature validation

See who signed a file, when, and whether every signature still checks out.

White-label

Light, dark and system themes at runtime. Build from source to compile in your name, logo and accent colour.

23 languages

The whole interface, translated. Pick a locale or follow the browser.

  • Encrypted PDFs (AES-256)
  • Export to Word, images and HTML
  • PDF/A
  • Accessibility checker
  • Bookmarks
  • Attachments
  • Watermarks & Bates numbers
  • Flatten
  • Print
  • Search
  • XFDF in and out
  • Undo & redo

Modes and features

One option. The right interface.

Drag the handle: the same viewer in full mode and in view mode. Every editing tool, panel and menu entry is gone, from the toolbars down to the right-click menus.

Free PDF SDK in view mode: only the document, search and navigation Free PDF SDK in view mode, dark theme: only the document, search and navigation
Free PDF SDK in full mode: the Tools panel, quick toolbar, menus and every panel Free PDF SDK in full mode, dark theme: the Tools panel, quick toolbar, menus and every panel
mode: "full" mode: "view"

mode

ts

Integrations

Drop it into the framework you already use

First-class components for React and Vue, an action for Svelte, and a Web Component for Angular and everything else. One npm package, fully typed.

tsx
import { useRef } from "react";
import { FreePdfViewer, type FreePdfViewerHandle } from "free-pdf-sdk/react";

export function ProofReview({ url }: { url: string }) {
  const ref = useRef<FreePdfViewerHandle>(null);
  return (
    <FreePdfViewer
      ref={ref}
      baseUrl="/free-pdf-sdk/"
      mode="annotate"
      features={{ stamps: false }}
      document={{ url }}
      onAnnotationsChanged={async () => {
        const xfdf = await ref.current?.viewer()?.exportXfdf();
        if (xfdf) await fetch("/api/comments", { method: "PUT", body: xfdf });
      }}
      style={{ height: "80vh" }}
    />
  );
}
vue
<script setup lang="ts">
import { ref } from "vue";
import { FreePdfViewer } from "free-pdf-sdk/vue";

const viewer = ref();
const count = ref(0);
</script>

<template>
  <FreePdfViewer
    ref="viewer"
    base-url="/free-pdf-sdk/"
    mode="annotate"
    :features="{ stamps: false }"
    :document="{ url: '/files/proof.pdf' }"
    @annotations-changed="(e) => (count = e.count)"
    style="height: 80vh"
  />
</template>
ts
// main.ts: register <free-pdf-viewer> once.
import { defineFreePdfViewer } from "free-pdf-sdk/element";
defineFreePdfViewer();

// proof-review.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";

@Component({
  selector: "app-proof-review",
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <free-pdf-viewer
      base-url="/free-pdf-sdk/"
      mode="annotate"
      src="/files/proof.pdf"
      [features]="{ stamps: false }"
      (fps-annotations-changed)="count = $any($event).detail.count"
      style="height: 80vh"></free-pdf-viewer>`,
})
export class ProofReviewComponent {
  count = 0;
}
svelte
<script>
  import { freePdf } from "free-pdf-sdk/svelte";
  let mode = "annotate";
  let count = 0;
</script>

<div
  style="height: 80vh"
  use:freePdf={{ baseUrl: "/free-pdf-sdk/", mode, document: { url: "/files/proof.pdf" } }}
  on:fps-annotations-changed={(e) => (count = e.detail.count)}
></div>
html
<script type="module">
  import { defineFreePdfViewer } from "free-pdf-sdk/element";
  defineFreePdfViewer();
</script>

<free-pdf-viewer
  base-url="/free-pdf-sdk/"
  src="/files/proof.pdf"
  mode="fill"
  ui='{"panels": {"layers": false}}'
  style="height: 80vh"></free-pdf-viewer>
ts
import { FreePdf } from "free-pdf-sdk";

const viewer = await FreePdf.init(document.getElementById("viewer")!, {
  baseUrl: "/free-pdf-sdk/",
  mode: "annotate",
  features: { stamps: false, measurement: false },
  ui: { panels: { layers: false } },
  author: "Ada Lovelace",
  document: { url: "/files/proof.pdf" },
});

viewer.on("annotationsChanged", ({ count }) => console.log(count, "comments"));
const xfdf = await viewer.exportXfdf();

How it works

Three steps to a working viewer

The viewer is a WebAssembly app in an iframe on your own origin. A small typed wrapper talks to it, so your code stays simple and your page stays isolated.

  1. 1

    Install

    Add the package to your app.

    npm install free-pdf-sdk
  2. 2

    Serve the viewer

    Copy the viewer files into a folder your site serves, on the same origin.

    npx free-pdf-sdk copy-viewer public/free-pdf-sdk
  3. 3

    Mount it

    Give an element a height and initialise it with a mode and a document.

    FreePdf.init(el, { baseUrl, mode })

Documentation

Docs written for developers

Guides for every framework, a full API reference and recipes for common setups.

  • Getting started in five minutes
  • Modes, features and interface options
  • Storing comments as XFDF
Read the docs

For AI agents

Docs your coding assistant can read

Every page is also plain Markdown, indexed in /llms.txt, with a JSON Schema of the options so agents generate valid configurations.

  • /llms.txt and /llms-full.txt
  • /docs/<page>.md for every page
  • /schema/viewer-options.schema.json
Docs for AI agents

See it with your own documents

Open a PDF in the live demo, toggle its layers and switch modes. Nothing is uploaded.