One PDF engine for every web framework.
InkLayer Core is a headless, framework-agnostic PDF interaction engine for the web. Use it to build custom document viewers, annotation systems, rule-driven keyword review and secure redaction workflows with React, Vue, any other framework, or vanilla TypeScript—while your application retains full control of the UI and product workflow.
Getting started · Live demo · Documentation
Install the package:
npm install @inklayer-dev/coreProvide a root element and a scroll container:
<div id="pdf-workspace">
<div id="pages"></div>
</div>Give the scroll container an explicit size:
html, body, #pdf-workspace {
height: 100%;
margin: 0;
}
#pages {
height: 100%;
overflow: auto;
background: #f2f4f7;
}Create Core and load a PDF:
import { createInkLayer } from '@inklayer-dev/core/capabilities'
import '@inklayer-dev/core/style'
const root = document.querySelector<HTMLElement>('#pdf-workspace')!
const pages = document.querySelector<HTMLDivElement>('#pages')!
const core = await createInkLayer({
root,
pageFlow: { container: pages, scale: 'page-width' }
})
await core.load({ url: '/documents/review.pdf', range: 'auto' })This creates a virtualized, continuously scrolling Viewer with built-in zoom gestures. Call await core.destroy() when the page or framework component is unmounted. Text selection, annotation tools, search controls, and other product actions are enabled by your application as needed.
Core ships with a version-matched PDF.js Worker. Ordinary Vite and Webpack applications do not need to download, copy, or configure pdf.worker.
Continue with the complete tutorial →
- Load PDFs from URLs or local bytes, including HTTP Range requests, passwords, progress, cancellation, and retry.
- Display single, continuous, or facing pages with virtual rendering, zoom, navigation, thumbnails, and outlines.
- Search PDF text and turn real text selections into markup annotations.
- Scan prepared literal and regular-expression rules in one batch, preview color-coded matches, review individual occurrences, and turn accepted results into permanent highlights.
- Keep sensitive terms readable during review, then print or export a securely redacted, image-only PDF whose source text cannot be selected or copied.
- Create and edit 16 built-in annotation types, including text markup, shapes, freehand drawing, notes, stamps, and signatures.
- Manage serializable annotation data with authors, comments, references, appearance, and client-side permission rules.
- Add watermarks and generate printable PDFs, annotated PDFs, secure raster print output, or annotation workbooks.
- Run multiple isolated instances, report structured errors, release resources deterministically, and import packages safely during SSR.
Create your first annotation →
The Keyword Highlighter accepts application-owned terms and regular expressions—for example contract clauses, prohibited wording, account numbers, or dates. It scans them together, renders temporary highlights by rule, and exposes an immutable review state for your own result list, filters, and controls. Accepted matches can become standard PDF Highlight annotations without reimplementing text geometry.
Secure keyword redaction reuses those reviewed matches but keeps preview and output separate. Reviewers see the normal Highlighter colors on screen; only Print or Export produces opaque coverings in a new image-only PDF. The generated file contains no source text objects, so covered content cannot be recovered by selecting the black area and copying the text underneath. This security path intentionally flattens all text, links, forms, and vector content in the exported copy.
Try keyword highlighting · Try secure redaction
InkLayer Core is headless: it provides the document engine and interaction APIs, not a finished toolbar or application shell.
| InkLayer Core | Your application or framework adapter |
|---|---|
| PDF loading, pages, layouts, zoom, and navigation | Viewer layout, controls, routing, and loading states |
| Search, outlines, thumbnails, and text-selection data | Search field, result list, sidebar, and selection menu |
| Annotation tools, gestures, transforms, and canonical data | Toolbar, appearance controls, comment panels, and dialogs |
| Client-side author and permission checks | Trusted identity and authoritative backend permission checks |
| Repository operations and change events | Server persistence, synchronization, and conflict handling |
| Watermark, print, PDF, and Excel generation APIs | Buttons, filenames, uploads, downloads, and invocation timing |
See Core boundary for the complete responsibility model.
- Vanilla JavaScript: build a Viewer with navigation, thumbnails, a toolbar, and an annotation list.
- Vue: keep one Core instance in the component and connect it to Vue state and lifecycle.
- React: keep one Core instance in a ref and connect it to React state and effects.
The same Core APIs can also be used from Svelte, Angular, Web Components, or another client framework.
Capability plugins connect one instance to application services such as logging, authenticated PDF requests, text input, annotation storage, printing, and downloads. Some services are called automatically by Core; print and download services are called explicitly by the application.
Custom annotation types add namespaced tools with their own data validation, creation behavior, renderer, and output support. Extensions work through public contracts and do not receive mutable Konva nodes or PDF.js private state.
Applications that mount pages themselves can create the Viewer directly. Worker configuration remains automatic:
import { createPdfViewerEngine } from '@inklayer-dev/core/viewer'
const viewer = createPdfViewerEngine()Override workerSrc only when a self-hosted CSP or deployment policy requires it:
const viewer = createPdfViewerEngine({
workerSrc: '/assets/pdf.worker.min.mjs'
})| Entry | Purpose |
|---|---|
@inklayer-dev/core |
Annotation data, validation, Repository, browser helpers, and shared types |
@inklayer-dev/core/capabilities |
createInkLayer() and Capability plugins |
@inklayer-dev/core/viewer |
PDF Viewer and Page Flow |
@inklayer-dev/core/annotation |
Annotation engine and interactions |
@inklayer-dev/core/annotation-types |
Built-in and custom annotation type definitions |
@inklayer-dev/core/highlighter |
Headless literal/regex scanning, review, preview, and permanent highlighting workflow |
@inklayer-dev/core/import/pdfjs |
Native PDF annotation import through PDF.js |
@inklayer-dev/core/export/pdf |
Annotated PDF and printable PDF generation |
@inklayer-dev/core/export/excel |
Annotation workbook generation |
@inklayer-dev/core/style |
Scoped engine CSS |
- Browser engines: tested with current Playwright builds of Chromium, Firefox, and WebKit
- Application builds: Vite, Webpack browser builds, and Node SSR imports
- Node tooling:
^22.13.0 || >=24.0.0
Embedded WebViews require separate verification. See browser support and the public API.
npm install
npm run dev # source-backed Vanilla example
npm run docs:dev # VitePress documentation
npm run check # complete release quality gateReleased under the MIT License.