npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lightpdf-sdk/editor

v1.0.7

Published

LightPDF Web PDF editor SDK for browser applications.

Readme

LightPDF Editor SDK

@lightpdf-sdk/editor is a browser-based PDF editor SDK with annotations, content editing, page management, forms, signatures, undo/redo, localization, and saving.

It provides two primary integration surfaces:

  • Web Component with the built-in UI — recommended for most applications.
  • Headless Core + Viewport — for applications that build their own toolbar, panels, and workflow.

The Web Component works with Vue, React, Angular, Svelte, and plain JavaScript. Its built-in UI is isolated with Shadow DOM.

Live demo and contact

Explore the complete editing experience in the LightPDF Editor SDK online demo.

To discuss SDK integration, licensing, private deployment, or other product requirements, contact the LightPDF team.

Installation

npm install @lightpdf-sdk/editor

Choose an integration

| Integration | Import | UI | Recommended for | | --- | --- | --- | --- | | Web Component | @lightpdf-sdk/editor/element | Complete built-in UI | Most product integrations | | JavaScript factory | @lightpdf-sdk/editor | Complete built-in UI | Creating and configuring the element from code | | Headless Core | @lightpdf-sdk/editor/core | Viewport only | Fully custom toolbars and workflows | | iframe host | Separate hosted page and protocol | Complete hosted UI | Strong isolation or iframe billing workflows |

The hiddenMenu, hiddenOptions, url, and similar query parameters belong to the hosted iframe/application adapter. They are not npm SDK options. See iframe integration.

Quick start: built-in UI

Importing the /element entry registers <light-pdf-editor> automatically:

import "@lightpdf-sdk/editor/element";
<light-pdf-editor
  id="pdf-editor"
  api-key="your-api-key"
  locale="zh"
  mode="annot"
></light-pdf-editor>

<input id="pdf-file" type="file" accept="application/pdf" />

The host must give the editor an explicit size:

light-pdf-editor {
  display: block;
  width: 100%;
  height: 100vh;
}

Open and save a PDF:

import type { LightPdfEditorElement } from "@lightpdf-sdk/editor";

const editor = document.querySelector<LightPdfEditorElement>("#pdf-editor")!;
const fileInput = document.querySelector<HTMLInputElement>("#pdf-file")!;

await editor.ready;

fileInput.addEventListener("change", async () => {
  const file = fileInput.files?.[0];
  if (file) await editor.openPdf(file);
});

async function downloadEditedPdf() {
  const file = await editor.savePdf();
  if (!file) return;

  const objectUrl = URL.createObjectURL(file);
  const link = document.createElement("a");
  link.href = objectUrl;
  link.download = file.name || "edited.pdf";
  link.click();
  URL.revokeObjectURL(objectUrl);
}

Call editor.destroy() when the host owns the element lifecycle and needs to remove it explicitly.

Create the built-in UI from JavaScript

Use createLightPdfEditor() when configuration is easier to provide as JavaScript properties:

import {
  createLightPdfEditor,
  type LightPdfEditorElement,
} from "@lightpdf-sdk/editor";

const editor: LightPdfEditorElement = createLightPdfEditor({
  target: "#pdf-editor-container",
  apiKey: "your-api-key",
  locale: "zh",
  mode: "form",
  activeTool: "form-select",
  noAutoDownload: true,
});

await editor.ready;
await editor.openPdf(file);

createLightPdfEditor() registers the custom element if necessary and appends it to target when a target is provided.

Headless Core + Viewport

@lightpdf-sdk/editor/core does not include the default Header, Toolbar, Sidebar, dialogs, or Vue UI. Use it only when your application supplies those controls.

import { createPdfEditorCore } from "@lightpdf-sdk/editor/core";
import "@lightpdf-sdk/editor/viewport.css";

const editor = createPdfEditorCore({
  viewer: document.querySelector<HTMLElement>("#pdf-viewer")!,
  viewportHeight: "100%",
  apiKey: "your-api-key",
  locale: "zh",
  mode: "annot",
});

await editor.ready;

const openResult = await editor.commands.document.open(file);
if (!openResult.ok) {
  console.error(openResult);
}

const unsubscribe = editor.subscribe(
  (state) => state.document.currentPage,
  (pageNumber) => console.log("Current page:", pageNumber),
  { emitInitial: true },
);

await editor.commands.view.zoomIn();

unsubscribe();
editor.destroy();

The viewer can be an HTMLElement, ShadowRoot, or selector. It can also be omitted and mounted later with editor.mountViewport(target).

Core commands return structured results instead of relying on exceptions for normal unavailable or cancelled states. Read capabilities with getCapabilities() or getActionAvailability() before presenting an action in custom UI.

For framework examples and controlled page operations, see Headless Core integration.

Runtime resources and CDN routing

The npm package contains the SDK JavaScript, type declarations, and the structural Viewport stylesheet. WASM, default-UI assets, the font worker, and font files are loaded at runtime.

Default runtime resources are selected from the editor instance locale:

| Instance locale | Default CDN | | --- | --- | | locale: "zh" | https://qncdn.aoscdn.com | | Any other locale | https://cfcdn.apowersoft.info |

Therefore this Core configuration uses the domestic CDN without any additional CDN option:

const editor = createPdfEditorCore({
  viewer: document.querySelector("#pdf-viewer")!,
  apiKey: "your-api-key",
  locale: "zh",
});

Set locale: "zh" explicitly when domestic routing must not depend on browser language or legacy URL parameters.

Default resource paths are:

/assets/lightpdf/edit-pdf/style.css
/assets/lightpdf/edit-pdf/bundledFontDownloadWorker.js
/wasm/lightpdf/pdf-edit/pdf-sdk.js
/wasm/lightpdf/pdf-edit/pdf-sdk.wasm
/font/lightpdf/pdf-edit/

Self-host runtime resources

Override all three resource directories for an offline, private, or customer-owned deployment:

const editor = createLightPdfEditor({
  target: "#pdf-editor-container",
  apiKey: "your-api-key",
  locale: "zh",
  assetBaseUrl: "https://static.example.com/lightpdf/edit-pdf/",
  wasmBaseUrl: "https://static.example.com/wasm/lightpdf/pdf-edit/",
  fontBaseUrl: "https://static.example.com/font/lightpdf/pdf-edit/",
});

Each option must point to a directory, not an individual file:

assetBaseUrl/
├── style.css
└── bundledFontDownloadWorker.js

wasmBaseUrl/
├── pdf-sdk.js
└── pdf-sdk.wasm

fontBaseUrl/
└── ...font files

Cross-origin servers must enable CORS and return JavaScript, CSS, WASM, and font files with the correct MIME types. See runtime resources and private deployment.

Common options

| HTML attribute | JavaScript option/property | Default | Description | | --- | --- | --- | --- | | api-key | apiKey | empty | SDK authorization key. | | locale | locale | environment fallback | Editor language and default CDN routing. | | mode | mode | annot | Initial mode: annot, edit, page, form, or sign. | | active-tool | activeTool | mode default | Initial built-in tool. | | readonly | readonly | false | Prevents document mutations. | | local-fonts | localFonts | true | Enables browser local-font discovery when supported. | | asset-base-url | assetBaseUrl | locale CDN | Directory for default-UI CSS and the font worker. | | wasm-base-url | wasmBaseUrl | locale CDN | Directory containing pdf-sdk.js and pdf-sdk.wasm. | | font-base-url | fontBaseUrl | locale CDN | Font resource directory. | | hidden-open-file | hiddenOpenFile | false | Hides the built-in open-file entry. | | no-auto-download | noAutoDownload | false | Prevents the built-in Save button from downloading automatically. | | theme | theme | default | Theme name for the built-in UI. | | expose-global-for-debug | exposeGlobalForDebug | false | Exposes debug state; do not enable in production. |

JavaScript-only built-in UI options include themeConfig, icons, messages, ui, renderers, and customTools.

Supported locales and tool names are exported as the PdfEditorLocale, PdfEditorMode, and PdfEditorTool TypeScript types.

Web Component methods

| Method | Result | Description | | --- | --- | --- | | ready | Promise<void> | Resolves after the component is mounted. | | openPdf(file, options?) | Promise<void> | Opens a File or Blob; supports options.password. | | savePdf() | Promise<File \| null> | Saves the current document. | | undo() / redo() | Promise<boolean> | Executes history navigation. | | getUndoRedoState() | { canUndo, canRedo } | Reads history availability. | | jumpToPage(pageNumber) | Promise<void> | Jumps to a 1-based page number. | | zoomIn() / zoomOut() | Promise<void> | Changes Viewport zoom. | | setMode(mode) | void | Switches editor mode. | | setTool(tool) | void | Activates a built-in tool. | | setLocale(locale) | void | Changes the UI locale. | | destroy() | void | Removes the element and releases the instance. |

getDebugStoreSnapshot() remains available for 1.x compatibility but is deprecated. Its internal result is not a stable API.

Web Component events

Events are composed CustomEvents and cross the Shadow DOM boundary.

editor.addEventListener("open-pdf-callback", (event) => {
  console.log(event.detail.success, event.detail.message);
});

editor.addEventListener("download-pdf", (event) => {
  console.log(event.detail.file);
});

editor.addEventListener("license-error", (event) => {
  console.error(event.detail.status, event.detail.message);
});

Frequently used events include:

  • ready, load-complete
  • open-pdf-callback, download-pdf, download-click
  • license-status-change, license-error
  • home-click, tool-click
  • options-change, theme-change
  • error, renderer-error, custom-tool-error

The exported PdfEditorEventMap contains the complete typed event details.

Theme and UI customization

Use stable theme tokens for lightweight branding:

const editor = createLightPdfEditor({
  target: "#container",
  theme: "customer-brand",
  themeConfig: {
    "--lp-theme-primary": "#2563eb",
    "--lp-theme-text": "#102033",
    "--lp-font-family": "Inter, sans-serif",
    "--lp-radius-control": "8px",
  },
  messages: {
    en: {
      "common.openFile": "Choose contract",
      "common.savePdf": "Export contract",
    },
  },
});

Customization is instance-scoped. Do not depend on internal Shadow DOM classes or structure.

Advanced default-UI configuration, renderers, custom tools, and Controller APIs are currently experimental. Their compatibility versions are exported as constants. See:

iframe integration

The hosted iframe adapter is a separate integration surface. It uses URL parameters and postMessage, and may include host validation or billing behavior that is intentionally not part of npm Core.

See:

Troubleshooting

The editor is blank or only partially visible

Give the host element or Headless viewer an explicit width and height. Do not test through file://; use an HTTP server.

The SDK still loads the overseas CDN

Pass locale: "zh" or locale="zh" on the editor instance. Importing createPdfEditorCore alone does not select a region.

style.css, pdf-sdk.js, or pdf-sdk.wasm returns 404

Verify that each custom base URL points to its directory and preserves the required filenames. A CSS request returning HTML usually means the server returned a 404 page.

WASM fails with a MIME or CORS error

Serve .wasm as application/wasm and allow the editor origin to fetch all cross-origin runtime resources.

Missing API key

Set apiKey or api-key before opening or saving a protected document.

Browser requirements

  • Modern ES Modules and dynamic imports.
  • Custom Elements and Shadow DOM for the built-in UI.
  • WebAssembly, Canvas, Blob, and standard browser file APIs.
  • Correct CORS and CSP rules for external WASM, workers, fonts, and SDK modules.