{"id":14381,"library":"y-utility","title":"Yjs Utilities","description":"y-utility provides essential helper functionalities for Yjs, a CRDT implementation for collaborative applications. The current stable version is 0.1.4, with releases occurring periodically to address bugs and integrate with newer Yjs versions. Key features include `YMultiDocUndoManager`, which extends Yjs's built-in `UndoManager` to handle undo/redo operations across multiple `Y.Doc` instances, essential for managing complex, nested document structures. It also offers `YKeyValue`, an optimized key-value store designed to address performance inefficiencies and document size growth observed when using `Y.Map` for frequently updated, alternating key-value pairs, thereby reducing metadata overhead and improving encoding size. This library targets environments running Node.js version 16 or newer, aligning with modern JavaScript module standards.","status":"active","version":"0.1.4","language":"javascript","source_language":"en","source_url":"https://github.com/yjs/y-utility","tags":["javascript"],"install":[{"cmd":"npm install y-utility","lang":"bash","label":"npm"},{"cmd":"yarn add y-utility","lang":"bash","label":"yarn"},{"cmd":"pnpm add y-utility","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for core Yjs functionality. This library extends and optimizes features of Yjs.","package":"yjs","optional":false}],"imports":[{"note":"This utility is exported from a subpath. Attempting to import directly from the main package path will fail. This package targets ESM primarily, though CJS exports are available via 'require' for specific subpaths like './dist/y-multidoc-undomanager.cjs'.","wrong":"import { YMultiDocUndoManager } from 'y-utility'","symbol":"YMultiDocUndoManager","correct":"import { YMultiDocUndoManager } from 'y-utility/y-multidoc-undomanager'"},{"note":"This utility is exported from a subpath. While CommonJS `require` is technically supported for `./dist/y-keyvalue.cjs`, the primary usage pattern for Node.js >=16 is ESM `import`.","wrong":"const { YKeyValue } = require('y-utility/y-keyvalue')","symbol":"YKeyValue","correct":"import { YKeyValue } from 'y-utility/y-keyvalue'"},{"note":"Yjs itself uses named exports for its core types like `Y.Doc`, `Y.Map`, `Y.Array`. Importing with a namespace `* as Y` is the conventional and correct approach.","wrong":"import Y from 'yjs'","symbol":"* as Y","correct":"import * as Y from 'yjs'"}],"quickstart":{"code":"import * as Y from 'yjs';\nimport { YMultiDocUndoManager } from 'y-utility/y-multidoc-undomanager';\n\nconst ydoc1 = new Y.Doc();\nconst ymap1 = ydoc1.getMap('my-map');\nconst ydoc2 = new Y.Doc();\nconst yarray2 = ydoc2.getArray('my-array'); // Changed from ydoc1 to ydoc2 to correctly show multi-doc\n\n// Create a multi-document undo manager tracking ymap1 initially\nconst um = new YMultiDocUndoManager([ymap1]);\n\n// Add yarray2 to the scope dynamically\num.addToScope([yarray2]);\n\n// Perform some operations on both documents\nymap1.set('a', 1);\nyarray2.insert(0, ['hello']);\nymap1.set('b', 2);\n\nconsole.log('Initial state:');\nconsole.log('ymap1:', ymap1.toJSON());\nconsole.log('yarray2:', yarray2.toArray());\n\n// Undo the last operation (ymap1.set('b', 2))\num.undo();\nconsole.log('\\nAfter first undo:');\nconsole.log('ymap1:', ymap1.toJSON()); // { a: 1 }\nconsole.log('yarray2:', yarray2.toArray()); // ['hello']\n\n// Undo the next operation (yarray2.insert(0, ['hello']))\num.undo();\nconsole.log('\\nAfter second undo:');\nconsole.log('ymap1:', ymap1.toJSON()); // { a: 1 }\nconsole.log('yarray2:', yarray2.toArray()); // []\n\n// Undo the first operation (ymap1.set('a', 1))\num.undo();\nconsole.log('\\nAfter third undo:');\nconsole.log('ymap1:', ymap1.toJSON()); // {}\nconsole.log('yarray2:', yarray2.toArray()); // []\n\n// Redo an operation (ymap1.set('a', 1))\num.redo();\nconsole.log('\\nAfter first redo:');\nconsole.log('ymap1:', ymap1.toJSON()); // { a: 1 }\nconsole.log('yarray2:', yarray2.toArray()); // []\n","lang":"typescript","description":"Demonstrates how to set up and use `YMultiDocUndoManager` to manage undo/redo history across multiple `Y.Doc` instances and their shared types."},"warnings":[{"fix":"Update imports and class instantiations from `MultiDocUndoManager` to `YMultiDocUndoManager`.","message":"The `MultiDocUndoManager` class was renamed to `YMultiDocUndoManager` in version `0.1.2`. Code relying on the old name will break.","severity":"breaking","affected_versions":"<0.1.2"},{"fix":"For datasets approaching or exceeding 1 million objects, monitor performance closely. Consider alternative data structures or custom optimizations if `YKeyValue` becomes a bottleneck. The core Yjs team is exploring future solutions.","message":"When using `YKeyValue` with extremely large collections (e.g., over 1 million objects), performance may degrade due to frequent calls to `yarray.toArray()`. This is a known limitation acknowledged by the developers, pending future Yjs optimizations.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"For dynamic key-value scenarios with frequent updates and deletions, use `YKeyValue` instead of `Y.Map` to benefit from optimized document size and performance.","message":"While `Y.Map` is a general-purpose map, it is inefficient for key-value stores with frequently alternating key updates and deletions. This can lead to significantly larger document sizes due to Yjs's conflict resolution mechanism retaining historical key values. `YKeyValue` from this library specifically addresses this.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Downgrade your `yjs` dependency to a version prior to 13.6.13, or check for updates to `y-utility` that explicitly address compatibility with `yjs` 13.6.13 and newer.","message":"In `yjs` v13.6.13, changes were introduced that break `YMultiDocUndoManager`, causing it to undo the entire stack instead of a single item. This affects `y-utility` users depending on this specific `yjs` version.","severity":"breaking","affected_versions":"yjs@~13.6.13"},{"fix":"Implement custom logic to manage the `undoStack` and `redoStack` properties of the undo manager, such as splicing them to limit their size, especially when items are popped off the stack, to allow underlying Yjs items to be garbage collected.","message":"The default `Y.UndoManager` (and by extension, `YMultiDocUndoManager`) disables garbage collection for items on its undo/redo stacks. If undo/redo operations are frequently alternated or stacks are not explicitly managed, this can lead to unbounded document size growth, even with otherwise efficient Yjs operations.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"search_vec":"'0.1.4':23 '16':110 'across':53 'address':29,76 'align':113 'also':65 'altern':90 'applic':17 'bug':30 'built':46 'built-in':45 'collabor':16 'complex':60 'crdt':13 'current':19 'design':74 'document':62,80 'encod':101 'environ':106 'essenti':7,57 'extend':42 'featur':38 'frequent':88 'function':9 'growth':82 'handl':50 'helper':8 'implement':14 'improv':100 'includ':39 'ineffici':78 'instanc':56 'integr':32 'javascript':116,119 'key':37,71,92 'key-valu':70,91 'librari':104 'manag':59 'metadata':97 'modern':115 'modul':117 'multipl':54 'nest':61 'newer':34,112 'node.js':108 'observ':83 'occur':26 'offer':66 'oper':52 'optim':69 'overhead':98 'pair':94 'perform':77 'period':27 'provid':6 'reduc':96 'releas':25 'run':107 'size':81,102 'stabl':20 'standard':118 'store':73 'structur':63 'target':105 'therebi':95 'undo/redo':51 'undomanag':48 'updat':89 'use':85 'util':2,5 'valu':72,93 'version':21,36,109 'y':4 'y-util':3 'y.doc':55 'y.map':86 'yjs':1,11,35,43 'ykeyvalu':67 'ymultidocundomanag':40","created_at":"2026-04-20T01:59:25.244574+00:00","updated_at":"2026-04-20T01:59:25.244574+00:00","problems":[{"fix":"Ensure you are importing from the correct subpath: `import { YMultiDocUndoManager } from 'y-utility/y-multidoc-undomanager'`.","cause":"Attempting to import `YMultiDocUndoManager` incorrectly, such as from the main 'y-utility' package instead of its specific subpath.","error":"TypeError: YMultiDocUndoManager is not a constructor"},{"fix":"For modern Node.js environments (>=16), use ESM `import`. If using CommonJS, check your bundler configuration or consider using the explicit CommonJS export path if available (e.g., `require('y-utility/dist/y-keyvalue.cjs')`).","cause":"The module resolver cannot find the specified subpath. This can happen if using CommonJS `require()` without a compatible `exports` map, or an outdated bundler.","error":"Error: Cannot find module 'y-utility/y-keyvalue'"},{"fix":"Install `yjs` with `npm install yjs@^13.5.29` or ensure your existing `yjs` version is within the compatible range.","cause":"The `yjs` package, a required peer dependency, is either missing from your project's `node_modules` or its installed version does not satisfy the `y-utility`'s required version range.","error":"Error: Peer dependency 'yjs@^13.5.29' not installed or incompatible."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":"https://docs.yjs.dev","github":"https://github.com/yjs/y-utility","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/y-utility","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}