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

@veltdev/nutrient-crdt

v1.0.1

Published

Velt CRDT wrapper for Nutrient Web SDK

Readme

@veltdev/nutrient-crdt

Vanilla Velt CRDT binding for Nutrient Web SDK documents.

Install

npm install @veltdev/nutrient-crdt @nutrient-sdk/viewer @veltdev/client @veltdev/crdt yjs y-protocols

Use @veltdev/nutrient-crdt-dev only when validating the development build output from this repository.

What It Syncs

The package stores Nutrient Instant JSON in a Velt CRDT Store with type: "map". The default content key is document. The wrapper strips volatile pdfId values before persistence. Annotations, form field values, comments, bookmarks, and supported Instant JSON metadata are included in the shared snapshot. Remote selections and cursors are published through Velt awareness because they are ephemeral presence state.

Quick Start

import NutrientViewer from '@nutrient-sdk/viewer';
import { createCollaboration } from '@veltdev/nutrient-crdt';

const instance = await NutrientViewer.load({
  container: document.querySelector('#viewer') as HTMLElement,
  document: '/sample.pdf',
  useCDN: true,
});

const manager = await createCollaboration({
  editorId: 'contract-2026',
  veltClient,
  instance,
});

Core APIs

createCollaboration(config) creates and initializes a CollaborationManager. manager.attachInstance(instance) binds an existing Nutrient viewer instance. manager.flushInstanceToStore(reason, true) exports Instant JSON and updates the Velt Store immediately. manager.applyInstantJson(instantJson) replaces the shared document snapshot. manager.addHighlight(input) adds an Instant JSON highlight annotation. manager.addComment(input) adds a portable comment payload. manager.setFormFieldValue(name, value) updates Instant JSON form field values. manager.saveVersion(name), getVersions(), getVersionById(id), restoreVersion(id), and setStateFromVersion(version) delegate to Velt CRDT version APIs. manager.forceReset(initialContent) replaces the shared state and reapplies it locally. manager.detachInstance() unbinds the viewer; manager.destroy() releases all subscriptions and overlays. manager.setLocalSelection(selection) and publishCurrentSelection(selection) publish ephemeral presence selections through awareness. manager.getRemoteSelections(), renderRemoteSelections(container), and clearRemoteSelectionOverlays() read and render remote presence overlays. manager.onStatusChange(cb), onSynced(cb), onRemoteSelectionsChange(cb), and onDocumentChange(cb) subscribe to status, sync, presence, and document changes; each returns an unsubscribe function. manager.getStore(), getDoc(), getMap(), getProvider(), getAwareness(), getInstance(), getDocumentState(), getInstantJson(), and getStats() expose typed escape hatches and diagnostics. Pure Instant JSON helpers (createDocumentState, mergeInstantJson, addHighlightToInstantJson, addCommentToInstantJson, setFormFieldValue, stripPdfId, diffInstantJson, getInstantJsonRecordId, and more) are exported for advanced snapshot handling.

Collaboration Model

Nutrient does not expose a public Yjs document model for Instant JSON. This wrapper stores full Instant JSON snapshots (with per-record envelopes) rather than operation-level PDF annotation CRDTs. Non-overlapping edits converge through the latest shared Instant JSON snapshot. Overlapping writes to the same annotation, comment, or form field resolve by the latest accepted Store update. Remote changes are applied per record: the manager diffs against a baseline and calls instance.create/update/delete/setFormFieldValues with only the delta, keeping the viewer's annotation layer flicker-free and the PDF unrewritten. Annotation identity travels in the record name (viewer-local ids are stripped from shared state) and is mapped to local viewer ids on receive. Pass the imported @nutrient-sdk/viewer module as the sdk config option so remote records are materialized with real SDK classes; records a viewer rejects are skipped locally and remain synced in the Store. Whole-document applyInstantJson is used only for viewer instances without granular record methods. Document-native attachments (base64 binaries) are not synced; unchanged Store keys are never rewritten, keeping per-change transport bounded. Applications with large documents should profile Instant JSON payload size and flush frequency.

Licensing

Nutrient Web SDK can run in trial mode without a license key. Production deployments should pass a valid licenseKey when creating the Nutrient viewer. Comments and some document editing features may require Nutrient license capabilities. The wrapper is framework-neutral and does not bundle a Nutrient license.

Documentation

See the repository demo/INTEGRATION.md for a complete Vite example, Velt initialization, multi-user testing, versions, persistence, awareness selections, and cleanup. See known-issues.md for snapshot conflict semantics and feature limitations.