Rune

Open source

TypeScript · MPL-2.0

The editor engine
under everything you write.

Framework-agnostic and open-source — the core that powers Zyler.

Live on npm

Blocks, not markup

Every document is a typed tree of blocks, not a string of Markdown. Read it, transform it, or persist it as clean JSON — the model is the source of truth and the UI just renders it.

  • Stable block IDs — reorder, nest, and reference without breaking links
  • Lossless JSON you can store, diff, and migrate against a schema
  • One document model, rendered identically on the server or the client
checklist.doc
Rendered
Launch checklist
Everything left before we ship the beta.
Wire the editor
Write the docs
Model · JSON
[
{ id: "h1", type: "heading" },
{ id: "p1", type: "text" },
{ id: "t1", type: "todo", done: true },
{ id: "t2", type: "todo", done: false },
]

Extend anything

Define a block in a few lines — a schema, a render function, optional commands — and it shows up everywhere: the slash menu, keyboard shortcuts, copy-paste, and serialization.

  • defineBlock() for custom blocks, defineMark() for inline styles
  • Hook into the command palette, input rules, and paste handlers
  • Ship a plugin as its own package — no fork required
callout-block.ts

Any framework

The core is plain TypeScript with zero UI dependencies. Thin adapters bind it to React, Vue, or Svelte, so the same editor — and the same plugins — run wherever your product lives.

  • @ocai/rune-core holds the model; adapters own only the view layer
  • One identical API across -react, -vue, and -svelte
  • Tree-shakeable ESM, SSR-ready, ~30kb core gzipped
App.tsx
ReactVueSvelte
import { RuneEditor } from "@ocai/rune-react"
 
export function App() {
return <RuneEditor doc={doc} />
}
Same core · same editor
Release notes
A block editor that renders the same everywhere.
Powered by one shared model

Bring Rune into your project

Install the package and start building on the open-source editor engine.

Live on npm