Notion-style blocks, streaming AI, Y.js collaboration, and a TipTap-inspired extension system — in a single ~45KB package. No ProseMirror. No license fees. Just install and ship.
Under MIT License • Structure and idea developed by mina-massoud @2025
Three lines. Working editor. Import, render, ship. Installation packages coming soon.
Provider-agnostic AI that streams content directly into blocks. OpenAI, Anthropic, Ollama, or your own endpoint.
Same CRDT engine behind Figma and VS Code Live Share. Y.js-powered conflict resolution with cursor presence.
Engineered from the ground up for zero-lag editing at any scale.
Each block subscribes only to its own slice of state. Type in block 5, blocks 1-4 and 6-200 don't know it happened.
State updates reuse unchanged references. React.memo skips re-renders automatically because the props literally haven't changed.
Critical text operations bypass React's virtual DOM entirely, writing to the DOM directly for sub-millisecond response times.
import { CompactEditor } from "@/components/ui/rich-editor"
function App() {
return (
<CompactEditor
initialContent={myContent}
onChange={({ json, html }) => {
saveToDatabase(json)
updatePreview(html)
}}
minHeight="300px"
/>
)
}const myProvider: AIProvider = {
generateStream: async function* (prompt) {
const stream = await openai.chat
.completions.create({
model: "gpt-4",
messages: [
{ role: "user", content: prompt }
],
stream: true
})
for await (const chunk of stream) {
yield chunk.choices[0]?.delta
?.content ?? ""
}
}
}
<CompactEditor ai={myProvider} />Provider-agnostic AI that streams content directly into blocks.
OpenAI, Anthropic, Ollama, or your own endpoint — implement one interface.
AI responses stream token-by-token directly into editor blocks in real time.
Markdown from the LLM is parsed into structured blocks as it arrives — headings, lists, code.
Users type /ai followed by a prompt to generate content inline.
AI-powered formatting — emphasize key words, add bold/italic, mark code terms. Smart styling, not just rephrasing.
Read content in any format. Set content programmatically. Full API access to every aspect of the editor.
Structured tree for storage and re-hydration
Semantic HTML — no Tailwind, no framework artifacts
CommonMark-compatible Markdown output
Raw text for search indexing and previews
const api = useEditorAPI()
// Read content in any format
const json = api.getJSON()
const html = api.getHTML()
const markdown = api.getMarkdown()
const text = api.getPlainText()
// Programmatic control
api.setContent(savedDocument)
api.insertBlock({
type: "heading-1",
content: "Hello"
})
// State checks
api.isDirty() // unsaved changes?
api.getBlockCount() // total blocksimport { CompactEditor, CollaborationProvider }
from "@/components/ui/rich-editor"
function CollabEditor() {
return (
<CollaborationProvider
roomId="my-document"
serverUrl="wss://your-server.com"
user={{
name: "Mina",
color: "#c8b4a0"
}}>
<CompactEditor />
</CollaborationProvider>
)
}Same CRDT engine behind Figma and VS Code Live Share. No server-side resolution needed.
Y.js-powered conflict-free replicated data types ensure every edit merges cleanly — even offline.
See where other users are typing in real time. Color-coded cursors with user names.
Wrap your editor in CollaborationProvider, point it at a WebSocket server, and you're live.
TipTap-inspired API with zero ProseMirror dependency. Build custom blocks, marks, and commands in minutes — not days.
Define new block types with styles, input rules, keyboard shortcuts, and slash-command registration. No schema language required.
Add custom inline marks — highlights, annotations, comments — that integrate with the selection toolbar automatically.
Register keyboard shortcuts, slash commands, and event hooks without defining new node types. Ship in one file.
Notion, Minimal, and GitHub themes out of the box. Override any token with CSS variables — full dark mode support included.
import { Node, StarterKit } from "@/components/ui/rich-editor"
// Define a custom callout block
const Callout = Node.create({
name: 'callout',
nodeType: 'callout',
group: 'block',
addStyles: () =>
'bg-blue-50 border-l-4 border-blue-500 p-4 rounded',
addInputRules: () => [{
find: /^!!! (.+)$/,
handler: (match, ctx) => {
// Convert "!!! text" → callout block
return true
}
}],
})
<CompactEditor
extensions={[StarterKit, Callout]}
/>Every feature is designed to save you time and reduce complexity.
Block-level reordering with visual drop indicators, nested block support, and touch-friendly handles for tablet users.
Full table editing — add and remove rows and columns, cell selection, and clean HTML table output.
Drag-to-upload, paste from clipboard, URL embedding, resize handles, alt text, and caption support.
Type # space for headings, ** for bold, ` for code, > for quotes, - for lists. Zero learning curve.
Floating toolbar appears on text selection with bold, italic, underline, strikethrough, code, link, and color options.
Pre-built document templates — blog post, meeting notes, project brief — that users can apply with one click.
Comprehensive shortcut system: Ctrl+B for bold, Ctrl+K for links, Ctrl+Shift+1-3 for headings, Tab for indent.
ARIA roles and labels on all interactive elements. Full keyboard navigation. Screen reader announcements for block operations.
100% TypeScript. Every prop, callback, type, and hook is fully typed. The type system is the documentation.
All editor styles are scoped. Your app's CSS won't break the editor. The editor's CSS won't break your app.
~45KB gzipped with zero ProseMirror dependency. TipTap ships 120KB+ with mandatory ProseMirror core. Mina's extension system adds zero overhead.
Comprehensive test suite: 759 unit tests (Vitest) and 210 E2E tests (Playwright) covering block operations, keyboard handling, serialization, and edge cases.
Build custom blocks, marks, and commands with Extension.create(), Node.create(), and Mark.create(). TipTap-inspired API, zero ProseMirror dependency.
3 built-in theme presets (Notion, Minimal, GitHub) — or create your own with CSS variables. Full dark mode support.
Mina Rich Editor is a free, open-source React block-based rich text editor that provides Notion-style block editing, built-in AI content generation, and Y.js-powered real-time collaboration in a single ~45KB gzipped package with zero ProseMirror dependency. It is built with TypeScript, shadcn/ui, and Tailwind CSS, and is MIT-licensed for commercial use.
Mina Rich Editor is ~45KB gzipped versus TipTap's 120KB+, requires no ProseMirror dependency, and includes built-in AI streaming, real-time collaboration, an extension system with Node.create()/Mark.create()/Extension.create(), and 3 theme presets — all at no cost. TipTap requires ProseMirror as a mandatory peer dependency, charges for collaboration and AI features, and offers no built-in themes. Mina Rich Editor is fully MIT-licensed with no commercial restrictions.
Mina Rich Editor supports 15+ block types including paragraphs, headings (H1–H4), ordered and unordered lists, code blocks, blockquotes, tables with row and column manipulation, images with drag-to-upload and resize, horizontal rules, toggle blocks, and cover images. All block types support drag-and-drop reordering and nesting.
Yes. Mina Rich Editor has built-in AI integration that works with OpenAI, Anthropic Claude, Google Gemini, Ollama, or any custom endpoint. AI responses stream token-by-token directly into editor blocks, and Markdown output is parsed into structured blocks (headings, lists, code) as it arrives. Users can type /ai followed by a prompt to generate content inline.
Yes. Mina Rich Editor is completely free and open-source under the MIT license. There are no commercial restrictions, no paid tiers, and no feature gating. AI integration, real-time collaboration, and all 15+ block types are included at no cost.
Yes. Mina Rich Editor includes Y.js CRDT-powered real-time collaboration with cursor presence, user name labels, and conflict-free merging — even for offline edits. Integration requires wrapping the editor in a CollaborationProvider and pointing it at a WebSocket server.
Mina Rich Editor exports content as JSON (structured tree for storage), semantic HTML (no Tailwind or framework artifacts), CommonMark-compatible Markdown, and plain text (for search indexing and previews). All formats are available via simple API calls: getJSON(), getHTML(), getMarkdown(), and getPlainText().
No ProseMirror dependency. Simple, powerful extensions. No PhD required.