is in preview! Please wait for a v1.0.0 stable release before using this in production.


@pluv/react comes with hooks to manipulate history that are built on top of the CRDT library you are using.

  • For Yjs (@pluv/crdt-yjs), it is built on top of the UndoManager.
  • For Loro (@pluv/crdt-loro), this feature is not yet supported.

This will allow users to apply undos and redos to Pluv storage mutations.

Relevant Hooks

Undoing a storage mutation

Assume you have storage defined like so:

import { yjs } from "@pluv/crdt-yjs";
import { createBundle, createClient } from "@pluv/react";
import type { io } from "../server/io";

const client = createClient<typeof io>({ /* ... */ });

export const { createRoomBundle } = createBundle(client);

export const pluvRoom = createRoomBundle({
    initialStorage: yjs.doc(() => ({
        messages: yjs.array([
                message: "hello",
                name: "leedavidcs",

To undo a storage mutation, you will need to wrap your mutation with a transaction.

const transact = pluvRoom.useTransact();
const [messages, sharedType] = pluvRoom.useStorage();

// We can undo this
transact(() => {

// We can also access all shared types to undo like this
transact((tx) => {

// We cannot undo this

Then from anywhere within the PluvRoomProvider, you can undo your last transacted operation.

const undo = pluvRoom.useUndo();
const redo = pluvRoom.useRedo();