🖊️ A PDF viewer and annotation SDK for React applications
For building document review, collaborative annotation, and commenting workflows
The fastest way to try InkLayer React: use the official starter 🚀 .
git clone https://github.com/Laomai-codefee/inklayer-react-starter.git
cd inklayer-react-starter
npm install
npm run devOpen:
💡 The starter comes with a complete PDF annotation example pre-configured — no extra setup needed to experience the full SDK.
- 🚀 PDF Viewer (zoom / search / theming)
- 🖍️ PDF Annotation System (highlight / ink / shapes / stamps / signatures)
- 💬 Comment & review workflow
- 🔗 Annotation references and cross-page navigation (
#references / hover previews / click-to-jump) - 🔐 Collaborative annotation permissions (ownership / admin overrides / read-only)
- 💾 Annotation data model (persistable)
- 📤 Export support (PDF / Excel)
- 🎨 Customizable UI (toolbar / sidebar)
- Fixed exports for native
/Lineannotations without/LE, with a regression test using the exact 595-byte PDF fixture - Preserved existing native PDF annotations when
enableNativeAnnotationsis disabled instead of removing them during export exportToPdfnow returns aPromise, allowing callers to await completion and handle export failures
- Refined annotation interactions: Sidebar and PDF synchronize on selection only, while Canvas hover keeps author labels without a distracting outline
- Fixed annotation navigation at automatic zoom, clipped Sidebar editors, and menu positioning after user or permission changes
- Improved PDF and Excel numbering: main PDF annotations use
Author · #N, while Excel uses stable#N / #N.1references - Localized annotation-type filters, preserved filter state, and polished collaborative permission and read-only behavior
- Restore a deleted annotation or reply before the notification disappears
- Fixed annotation selection state and the color picker's back, layout, and timer interactions
- Improved author-label collision handling, drag updates, and hover-preview layering
- Reference other annotations with
#from comments and replies - Preview referenced annotations, selected text, authors, pages, and replies on hover
- Jump between sidebar entries and PDF annotations, including across pages
- Improved annotation selection, editor focus, and hover interactions
npm install inklayer-reactimport { PdfAnnotator } from 'inklayer-react'
import 'inklayer-react/style'
export default function App() {
return (
<PdfAnnotator
title="PDF Annotator"
url="https://example.com/sample.pdf"
user={{ id: 'u1', name: 'Alice' }}
onSave={(annotations) => {
console.log('Saved annotations:', annotations)
}}
/>
)
}import { PdfViewer } from 'inklayer-react'
import 'inklayer-react/style'
export default function App() {
return (
<PdfViewer
title="PDF Viewer"
url="https://example.com/sample.pdf"
layoutStyle={{ width: '100vw', height: '100vh' }}
/>
)
}👉 https://inklayer.dev/docs/react
user is the current application user supplied by the host application. InkLayer uses this identity only to determine annotation and reply ownership; authentication remains the host application's responsibility, and callers do not need to provide a separate role. In owner-only mode, a current user with a valid user.id may create annotations and replies, while only the annotation owner may move, resize, edit, change status, or delete that annotation. A reply can be edited or deleted only by its author.
<PdfAnnotator
user={{ id: currentUser.id, name: currentUser.name }}
annotationPermissions={{
mode: 'owner-only',
// isAdmin is implemented by your application
can: ({ currentUser }) =>
isAdmin(currentUser?.id) ? true : undefined
}}
/>The optional synchronous can(request) resolver overrides the mode: return true to allow, false to deny, or undefined to keep the mode's default decision. The request includes action, currentUser, annotation, comment, and defaultAllowed, so applications can add administrator, workflow-state, or document-level rules.
For a fully read-only annotator, pass annotationPermissions={{ can: () => false }}. Users can still select and inspect annotations, while every mutation is denied.
These are browser interaction permissions for InkLayer UI and local mutations. Your backend API must still authorize every read and write; client-side decisions are not a security boundary.
- InkLayer Vue: https://github.com/Laomai-codefee/inklayer-vue
- Vue Starter: https://github.com/Laomai-codefee/inklayer-vue-starter
- React Starter: https://github.com/Laomai-codefee/inklayer-react-starter
The core InkLayer SDK is MIT licensed and free to use in personal and commercial projects.
- Questions and feature ideas: GitHub Discussions
- Bug reports: GitHub Issues
- Documentation: https://inklayer.dev/docs/react
Community support is provided on a best-effort basis as maintainer time allows, without a guaranteed response time.
Contact the maintainer if your project needs:
- React or Vue integration and troubleshooting
- Annotation persistence and backend integration
- User, role, and workflow permission integration
- Custom features or support for another framework
- Ongoing maintenance and priority response for a private project
Email: codefee@foxmail.com
Please include your use case, technology stack, required capabilities, and target timeline.
InkLayer React is browser-only and does not support server-side rendering (SSR). Its components depend on the DOM, Canvas, and Web Workers, so import and render them only in client-side code.
- Supports React 18 and React 19
- Supports Vite and Webpack 5
- Provides both ESM and CommonJS entry points; ESM is recommended
- In isomorphic frameworks such as Next.js or Remix, keep the components behind a client boundary and disable SSR for them
MIT © InkLayer
