# Edit history

- Human documentation: [https://docs.univer.ai/guides/bases/features/edit-history](https://docs.univer.ai/guides/bases/features/edit-history)

- Agent Markdown: [https://docs.univer.ai/guides/bases/features/edit-history.md](https://docs.univer.ai/guides/bases/features/edit-history.md)

- Requested language: `en-US`

- Content language: `en-US`

- Documentation version: `1.0.0-rc.0`

- Source: [bases/features/edit-history.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/bases/features/edit-history.mdx)

---

#### Package metadata

```json
{
  "preset": [],
  "plugins": [
    {
      "client": "@univerjs-pro/edit-history",
      "facade": "@univerjs-pro/edit-history/facade"
    },
    {
      "client": "@univerjs-pro/edit-history-ui",
      "locale": "@univerjs-pro/edit-history-ui/locale/en-US",
      "style": "@univerjs-pro/edit-history-ui/lib/index.css"
    },
    {
      "client": "@univerjs-pro/bases-history"
    },
    {
      "client": "@univerjs-pro/bases-history-ui",
      "locale": "@univerjs-pro/bases-history-ui/locale/en-US",
      "style": "@univerjs-pro/bases-history-ui/lib/index.css"
    }
  ],
  "server": "optional"
}
```

After you edit fields, records, or views, open history to inspect earlier versions, compare changes, and restore a version when permitted. History reads server-persisted versions. Undo and redo apply to the current editing session and do not require a history service.

## Prepare collaboration and history services

Complete [collaboration integration](https://docs.univer.ai/server/collaboration/browser-integration.md) and [license configuration](https://docs.univer.ai/server/license.md). Verify that two sessions can edit the same Bases document and that changes survive a reload.

Follow [Office collaboration extensions](https://docs.univer.ai/server/collaboration/extensions.md) and the [History example](https://docs.univer.ai/server/collaboration/examples.md#history) to connect history storage and permissions. Core collaboration does not enable history automatically. The backend must also support history lists, version content, and restoration.

## Add the history plugins

Add this to your existing product, license, and collaboration setup. If a preset or existing configuration already registers these plugins, update that configuration instead of registering them twice.

#### npm

```bash
npm install @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/bases-history @univerjs-pro/bases-history-ui
```

#### pnpm

```bash
pnpm add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/bases-history @univerjs-pro/bases-history-ui
```

#### yarn

```bash
yarn add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/bases-history @univerjs-pro/bases-history-ui
```

#### bun

```bash
bun add @univerjs-pro/edit-history @univerjs-pro/edit-history-ui @univerjs-pro/bases-history @univerjs-pro/bases-history-ui
```

```ts
import { UniverEditHistoryPlugin } from '@univerjs-pro/edit-history'
import EditHistoryLocale from '@univerjs-pro/edit-history-ui/locale/en-US'
import { UniverBasesHistoryPlugin } from '@univerjs-pro/bases-history'
import { UniverBasesHistoryUIPlugin } from '@univerjs-pro/bases-history-ui'
import HistoryLocale from '@univerjs-pro/bases-history-ui/locale/en-US'
import { LocaleType, mergeLocales } from '@univerjs/core'

import '@univerjs-pro/edit-history-ui/lib/index.css'
import '@univerjs-pro/bases-history-ui/lib/index.css'

const historyServerUrl = '/api/history'

univerAPI.loadLocales(LocaleType.EN_US, mergeLocales(EditHistoryLocale, HistoryLocale))
univer.registerPlugin(UniverEditHistoryPlugin, { historyServerUrl })
univer.registerPlugin(UniverBasesHistoryPlugin)
univer.registerPlugin(UniverBasesHistoryUIPlugin, {
  univerContainerId: 'app',
  historyServerUrl,
})
```

Replace `/api/history` with your application's history endpoint and ensure its API matches the client requests. Keep both `historyServerUrl` values identical. Set `univerContainerId` to the editor container's DOM ID, and load the locale that matches the editor.

The history viewer creates a separate read-only editor. For custom content, use `viewerPlugins` to add plugins that the viewer does not already include. Do not register built-in viewer plugins again.

## View and restore versions

Open history from the editor menu and select a version to inspect its content and changes. Restoring changes the current shared document. Only users with restore permission should be able to do so, and the server must enforce that permission.

To verify the integration, edit fields, records, or views, wait for collaboration confirmation, and inspect the history list and version content. Reopen the application and restart the service to check persistence. Restore an earlier version and verify that another browser session receives the restored state.

If the list is empty, check whether history was recorded for this document, then check the document ID and service URL. If viewing works but restoration fails, check restore permissions and the collaboration connection. Reading history also requires authorization because older versions may contain data that has since been deleted.

## Compare snapshots

To build a review screen or provide changes to an AI Agent, use `compareUnitData()` or prepare a comparison once with `prepareUnitComparison()`. Register the product History plugin and import the Facade entry. Supply two fully materialized snapshots of the same unit as `beforeSnapshot` and `afterSnapshot`; this read-only comparison does not require a history service and does not restore or merge content.

```ts
import { UnitComparisonDetailLevel, UnitComparisonFidelity } from '@univerjs-pro/edit-history'
import { UniverInstanceType } from '@univerjs/core'

import '@univerjs-pro/edit-history/facade'

const comparison = univerAPI.prepareUnitComparison({
  comparisonId: 'review-1',
  unitId: beforeSnapshot.id,
  type: UniverInstanceType.UNIVER_BASE,
  fidelity: UnitComparisonFidelity.SNAPSHOT,
  leftData: beforeSnapshot,
  rightData: afterSnapshot,
})
const overview = comparison.query({ detail: UnitComparisonDetailLevel.SUMMARY })
const scope = overview.scopes[0]
const page = comparison.query({ scope, offset: 0, limit: 100 })
console.log(page.items, page.page.hasMore, page.diagnostics)
```

Read `scopes` to discover available views, then pass a scope to `query()` to filter the result without rerunning the comparison. Results default to 100 items and accept up to 1,000 per page. Use `page.hasMore` with `offset` for additional items. `summary` describes the whole comparison, even when items are filtered. Check `diagnostics.readiness` and `diagnostics.codes` before treating the result as a complete comparison. For Node.js or CLI usage without an editor, see the [headless comparison API](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/edit-history.md#headless-comparison).
