Revise Developer Platform menu

Architecture

What the component owns, what you own, and how state is scoped.

These docs are for version 2.3.x. See the latest version.

The boundary#

The SDK owns

  • Parsing DOCX, ODT, RTF, Markdown, text, and HTML
  • The document model and its Yjs session
  • Canvas layout, pagination, and rendering
  • Keyboard input, selection, and undo history
  • Tracked changes and comment threads
  • The agent tool runtime

You own

  • The file: where it comes from, where it goes
  • Document IDs and their meaning
  • The collaboration transport, if you want one
  • Accounts, permissions, and tenancy
  • Persistence and versioning
  • Your agent loop and its model
  • Any chrome you choose to render yourself

The SDK does not call Revise servers. Its only possible network call is to an agent backend you configure. With collaboration, the SDK builds the shared document and reads awareness, and you open the socket. See collaboration. With @reviseio/editor/server, the process that relays updates can also create, read, and edit the document. See the backend reference.

Canvas rendering#

Revise is not built on ProseMirror, Slate, or a contenteditable DOM. It is a word processor rendered to <canvas>, with its own layout engine, text measurement, and hit testing.

Page geometry follows Word, not the web: pagination, per-section page sizes and margins, running headers and footers, footnote areas that flow with their references, and text measurement that matches the .docx export.

The document is not in the DOM. Every read and write goes through the handle or the tools. Selection geometry is not public: there are no canvas rectangle or hit-test APIs.

Document sessions#

ReviseEditor keeps every open document mounted. Editor-local state survives tab switches: caret and selection, scroll position, formatting context, search, review and comment state, zoom, and in-flight agent runs.

Every document-local controller supports two forms of routing:

TypeScript
editor.review.next();                        // the active document
editor.review.forDocument("exhibit-a").next(); // a specific one
editor.document("exhibit-a").review.next();    // equivalent

Collection state comes from editor.documents.getState() and editor.documents.subscribe(). Acting on the active document does not require reading state first.

Tool state is per document, not per call. Reads, edits, and searches persist across tools.execute() calls, so a search_result_id from one call can target matches in the next. Reloading a document's source starts a new tool session and invalidates those IDs.

Document fragments#

Each document stores content in separate fragments, as Word does:

FragmentHolds
contentThe document body. Block operations and agent indices see only this.
chromeRunning headers and footers, per side, slot, and section.
notesFootnote and endnote bodies, referenced inline from the body.

Inserting a footnote does not shift body block indices. "Block 12" is always body block 12, regardless of how many notes exist.

Editing modes#

Every document is in one of three modes, set per document and changed at runtime through view.setDocumentMode():

editing

Changes apply directly. The default.

suggesting

Changes land as tracked suggestions to accept or reject.

viewing

Read-only.

Agent tool calls (tools.call, tools.execute) make tracked changes by default, whatever mode the editor is in, so a person reviews them. A delegated agent.run() follows the document mode. Both take directMode: true to apply edits directly. See tracked changes and agent tools.

Mode is not a permission. Any code with the handle can change it. To prevent a participant from editing directly, set a role. A role limits which modes are available and refuses agent tool calls that exceed it.