Introduction
What the editor is built on, what it deliberately leaves out, the stack it needs, and a three-step quick start for a new project.
A block editor for React, built on Plate (platejs 53) with shadcn primitives. A document is JSON, checked against an allow list of block types, attributes and marks before it is opened or saved. The editor installs as a shadcn block, so the source lands in your own project and you can read or change every line of it.
What it is not
- No AI writing, no suggestions.
- No live collaboration and no presence. A save that loses a race reports a conflict and offers the user a reload.
- No import or export. The document is JSON in your storage; a Markdown export is yours to write.
- No upload backend and no file hosting. The editor stores whatever URL a FileUploadAdapter hands back.
- No server-side editor. Only the read-only renderer runs on the server; it has no hooks and no editing surface.
What you get
- Blocks
- Paragraph, headings, quote, divider, bookmark, image, file, video, audio, embed, page link, table of contents, equation, callout, toggle, code, table, columns, footnote definitions.
- Inline
- Link, mention, inline equation, inline date, footnote reference.
- Text styles
- Bold, italic, underline, strikethrough, inline code, superscript, subscript, keyboard, text color, highlight, font size, font family.
- Block attributes
- Text align, line height, indent, lists, restart numbering, to-do state, tones.
- Editing
- Slash menu, block menu, block handle, drag and drop, block selection, find and replace, undo and redo, paste, emoji suggestions, autosave, read-only mode.
Every block type has a static rendering, so saved content reads the same on the server as it does in the editor. The details are in the props and keyboard shortcut references.
Requirements
- React 19 and React DOM 19.
- A Next.js or Vite project. Nothing in the editor needs a framework beyond React.
- Tailwind CSS v4, because the blocks use v4 utilities and CSS variables.
- shadcn with Radix primitives. Base UI projects do not compile without changes, because the editor renders the Radix component APIs.
Quick start
Install the block and everything it depends on.
bunx --bun shadcn@latest add https://www.huanngdev.site/r/notion-like-editor.jsonPut the editor in a client component. Import it from the path shadcn wrote it to.
tsx"use client"; import { NotionLikeEditorBlock } from "@/components/blocks/notion-like-editor"; export function NotesEditor() { return <NotionLikeEditorBlock documentId="notes" />; }Render that component from a page. The document lives in memory until you pass an
adapter.