BeakBlock is a monorepo for a block-based rich text editor built on ProseMirror. The core idea is simple: the editor keeps a public ProseMirror surface instead of hiding it behind a private wrapper, and the framework packages expose that core cleanly for React and Vue.
packages/core- the editor engine, schema, plugins, markdown tools, collaboration hooks, comments, versioning, track changes, and compliance lock supportpackages/react- React hooks and components for embedding the editorpackages/vue- Vue 3 composables and components for embedding the editorexamples/next-app- Next.js React demo with a full-stack AI route, threaded comments, chart blocks, JSON inspection, markdown export, and DOCX/PDF exportexamples/vite-vue- Vue showcase with rich blocks, AI, comments, and custom chart blocksexamples/nuxt-vue- a larger Nuxt app showing collaboration, approvals, templates, and compliance workflowsdocs- the reference docs for blocks, markdown, comments, collaboration, styling, versioning, and publishing
BeakBlock is designed for teams that want a real editor runtime, not a black box.
- Public access to ProseMirror through
editor.pm.* - A JSON block model that can be stored, transformed, and restored
- First-class React and Vue integrations on top of the same core
- Built-in support for menus, tables, media, embeds, comments, AI entry points, versioning, track changes, and compliance locks
- Markdown import/export and clipboard paste support
- Optional collaboration via Y.js
- Custom block and custom mark support
| Package | Purpose |
|---|---|
@amusendame/beakblock-core |
Core editor engine, schema, commands, plugins, markdown, comments, versioning, collaboration, and styling |
@amusendame/beakblock-react |
React hooks, editor view, slash menu, bubble menu, AI modal, comments modal, table tools, and custom block helpers |
@amusendame/beakblock-vue |
Vue 3 composables, editor view, slash menu, bubble menu, AI modal, comments UI, table tools, chart block helpers, and custom block helpers |
Install only what you need:
pnpm add @amusendame/beakblock-core
pnpm add @amusendame/beakblock-core @amusendame/beakblock-react
pnpm add @amusendame/beakblock-core @amusendame/beakblock-vueFor collaboration features, also install:
pnpm add yjs y-prosemirror y-websocketimport { BeakBlockEditor } from '@amusendame/beakblock-core';
import '@amusendame/beakblock-core/styles/editor.css';
const editor = new BeakBlockEditor({
element: document.getElementById('editor'),
initialContent: [
{
type: 'heading',
props: { level: 1 },
content: [{ type: 'text', text: 'Hello BeakBlock', styles: {} }],
},
{
type: 'paragraph',
content: [{ type: 'text', text: 'Start editing...', styles: {} }],
},
],
});
console.log(editor.getDocument());
console.log(editor.pm.state);import {
useBeakBlock,
BeakBlockView,
SlashMenu,
BubbleMenu,
TableHandles,
} from '@amusendame/beakblock-react';
import '@amusendame/beakblock-core/styles/editor.css';
function Editor() {
const editor = useBeakBlock({
initialContent: [
{
id: '1',
type: 'paragraph',
props: {},
content: [{ type: 'text', text: 'Hello, React', styles: {} }],
},
],
});
return (
<>
<BeakBlockView editor={editor} />
<SlashMenu editor={editor} />
<BubbleMenu editor={editor} />
<TableHandles editor={editor} />
</>
);
}useBeakBlock() returns null until the editor is mounted, and BeakBlockView accepts that null state while it initializes.
<script setup lang="ts">
import { useBeakBlock, BeakBlockView } from '@amusendame/beakblock-vue';
const editor = useBeakBlock({
initialContent: [
{
id: '1',
type: 'paragraph',
props: {},
content: [{ type: 'text', text: 'Hello, Vue', styles: {} }],
},
],
});
</script>
<template>
<BeakBlockView :editor="editor" />
</template>The core package exposes the editor instance and the underlying ProseMirror objects directly. The main escape hatch is intentional, not hidden:
editor.pm.view
editor.pm.state
editor.pm.dispatch(tr)Documents are stored as arrays of Block objects. Built-in block families include:
- Text blocks such as
paragraph,heading,blockquote,callout, andcodeBlock - Structural blocks such as
divider - Lists such as
bulletList,orderedList,listItem,checkList, andcheckListItem - Layout blocks such as
columnList,column, andtableOfContents - Tables such as
table,tableRow,tableCell, andtableHeader - Media blocks such as
imageandembed
See the block reference in docs/blocks/README.md.
The core supports Markdown import/export and Markdown-aware paste handling.
markdownToBlocksblocksToMarkdownblocksToMdastRootmdastToBlockslooksLikeMarkdown
See docs/markdown.md.
Comments are selection-anchored threads stored outside the document JSON.
- Use
createCommentPlugin(store)to render annotations - Use
CommentStoreorInMemoryCommentStore - Call
store.mapAnchors(transaction.mapping)on document-changing transactions
See docs/comments.md.
The core supports snapshot storage through a pluggable adapter and a separate track-changes flow.
VersioningAdapterInMemoryVersioningAdaptersaveVersion,listVersions,getVersion,restoreVersionenableTrackChanges,disableTrackChanges,acceptTrackedChange,rejectTrackedChange
See docs/versioning.md.
Y.js collaboration is supported through optional peers:
yjsy-prosemirrory-websocket
The core includes compliance lock support for read-only headings and lock-aware drag/drop behavior.
complianceLockdragDrop.headingLockBadgeCOMPLIANCE_LOCK_BYPASS_META
See docs/compliance-lock.md and the compliance example in docs/compliance-demo.md.
Styles are auto-injected by default. If you want to control CSS yourself, disable injection and import the stylesheet manually.
import '@amusendame/beakblock-core/styles/editor.css';
const editor = new BeakBlockEditor({
injectStyles: false,
});See docs/styling.md.
@amusendame/beakblock-react exports:
useBeakBlockuseEditorContentuseEditorSelectionuseEditorFocususeDocumentVersionsBeakBlockViewSlashMenuBubbleMenuAIModalCommentModalCommentRailLinkPopoverTableMenuTableHandlesMediaMenuColorPicker
It also exports custom block helpers like createReactBlockSpec, createChartBlockSpec, useBlockEditor, and useUpdateBlock.
@amusendame/beakblock-vue exports:
useBeakBlockuseEditorContentuseEditorSelectionuseEditorFocususeDocumentVersionsBeakBlockViewSlashMenuBubbleMenuAIModalCommentModalCommentRailLinkPopoverTableMenuTableHandlesMediaMenuColorPicker
It also exports Vue custom block helpers such as createVueBlockSpec, createChartBlockSpec, useBlockEditor, and useUpdateBlock.
BeakBlock treats AI as a workflow entry point rather than a hardcoded model integration.
- The core provides AI context helpers and preset sets
- React and Vue provide an
AIModal - Slash menu and bubble menu can surface AI actions
- The shared example helper lives in
examples/shared/ai.ts
Useful core exports include:
buildAIContextBUBBLE_AI_PRESETSSLASH_AI_PRESETSgetAIPresets
examples/next-appdemonstrates the React editor in a Next.js App Router app with toolbar controls, document JSON, Markdown output, Office export helpers, and a server AI routeexamples/vite-vuedemonstrates the Vue package with AI, comments, a custom chart block, and a broad block showcaseexamples/nuxt-vuedemonstrates collaboration, approvals, templates, document release, comments, and export in a compliance-oriented workspace
Run them from the repo root with:
pnpm --filter @amusendame/beakblock-example-next-app dev
pnpm --filter @amusendame/beakblock-example-vite-vue dev
pnpm --filter @amusendame/beakblock-example-nuxt-vue devStart here:
docs/blocks/README.mddocs/markdown.mddocs/comments.mddocs/versioning.mddocs/collaboration.mddocs/custom-blocks.mddocs/custom-marks.mddocs/plugins.mddocs/styling.mddocs/compliance-lock.mddocs/compliance-demo.mddocs/publishing.md
From the repository root:
pnpm install
pnpm dev
pnpm build
pnpm test
pnpm lintPackage-level build and watch scripts live in each package and example app. The workspace is configured for Node 18+ and pnpm 8+.
Apache-2.0
