■ pointy/docs

Introduction

Pointy makes HTML editors collaborative — real-time and offline — with an open-source HTML sync CRDT and server-side doc storage. The engine (pointyink/rogue) is Apache-2.0; the managed sync server is the paid part. There are a few ways to integrate, depending on what you're building on.

  • HugeRTE plugin (@pointyink/hugerte) — one attachRogue() call and your HugeRTE editor is multi-user. MIT-licensed, no GPL question.
  • Raw engine (@pointyink/rogue) — bind any contenteditable or HTML-based app to the CRDT directly, and wire your own transport.

Install

# HugeRTE plugin
npm i @pointyink/hugerte hugerte

# Raw engine
npm i @pointyink/rogue

Quick start

For a HugeRTE editor, pass it attachRogue plus a WebSocket URL, a doc id, and a token provider:

import hugerte from 'hugerte'
import { attachRogue } from '@pointyink/hugerte'

hugerte.init({
  target: '#editor',
  custom_undo_redo_levels: 0,
  setup: async (editor) => {
    await attachRogue(editor, { wsUrl, docId, getToken })
  },
})

For your own HTML app, bind a contenteditable element to the engine and feed it remote ops through a sync client:

import { createRogueNode } from '@pointyink/rogue'
import { createSyncClient } from '@pointyink/rogue/sync-client'

const node = await createRogueNode({
  element: document.getElementById('editor'),
  onCommit: (payload) => client.send(payload),
})

const client = createSyncClient({
  wsUrl, docId, getToken,
  mergeOp: (payload) => node.mergeOp(payload),
})

Full API reference on the HugeRTE plugin and raw engine pages. Keys and tokens are covered in Authentication.

How it works

Every keystroke is an operation with a stable identity. Operations merge in any order, on any device, at any time, and converge on the exact same document — there is no "winner" and no "loser".

  • Offline-first — edits are applied locally and queued in IndexedDB; they replay automatically on reconnect.
  • Server-side storage — operations persist server-side, so reload, rejoin, and invite-a-teammate all "just work".
  • Roles & sharing — owners, editors, and public read-only links.
  • Anything HTML — the wire format is literally HTML, so decks, whiteboards, and dashboards can ride the same engine.

Concurrency model

The engine is a Fugue CRDT over a rope treap, compiled to WebAssembly. Documents are addressed by a content address that advances monotonically with every accepted operation; two replicas that have accepted the same operations hold the same content address.

Included: comments and suggested edits, built on the same CRDT anchors as cursors so they survive edits without touching the synced document. Coming soon: @mentions.