Skip to content
Development
Skill

/web-editor-tiptap

Headless rich text editor framework built on ProseMirror. Use when building an editor with TipTap — setup, extensions, custom nodes and marks, menus, node views, serialization.

From plugin
agents-inc-skills
24200 skills
Install
$ npx -y skills add agents-inc/skills --skill web-editor-tiptap --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/web-editor-tiptap

Context preview

The summary Claude sees to decide when to auto-load this skill.

Headless rich text editor framework built on ProseMirror. Use when building an editor with TipTap — setup, extensions, custom nodes and marks, menus, node views, serialization.

SKILL.md

web-editor-tiptap.SKILL.md
name: web-editor-tiptap
description: Headless rich text editor framework built on ProseMirror. Use when building an editor with TipTap — setup, extensions, custom nodes and marks, menus, node views, serialization.

TipTap Editor Patterns

> **Quick Guide:** TipTap is a headless editor: it owns the schema, the state and the behaviour, and > hands the UI entirely to you. Everything is an extension — Nodes define content that lives in the > document, Marks define formatting applied to ranges of text, and Extensions add behaviour without > touching the schema. Commands are chained and applied by `.run()`. JSON is the persistence format. > **Current: v3.x** — Floating UI replaced Tippy.js, menus moved to a `/menus` sub-path, and > StarterKit now includes Link and Underline.

**Detailed Resources:**

  • [examples/core.md](examples/core.md) — editor setup, toolbars, serialization and persistence, `useEditorState`, `EditorContext`
  • [examples/custom-extensions.md](examples/custom-extensions.md) — custom nodes and marks, input and paste rules, keyboard shortcuts, node views, extending built-ins
  • [examples/menus.md](examples/menus.md) — BubbleMenu, FloatingMenu, multiple menus, slash commands, fixed toolbars
  • [reference.md](reference.md) — StarterKit contents, schema and extension API tables, content expressions, v2 → v3 migration

---

Which path applies

  • **React** — `useEditor` returns the editor and `EditorContent` renders the editable area. Start at

[examples/core.md](examples/core.md).

  • **Vue or vanilla** — construct the `Editor` class from `@tiptap/core` directly. Every extension in

[examples/custom-extensions.md](examples/custom-extensions.md) is unchanged; only the adapter and the node-view renderer differ.

  • **Server-rendered** — the editor cannot render on the server at all. Set

`immediatelyRender: false` and let it mount on the client.

---

<critical_requirements>

Before writing TipTap code

**Set `immediatelyRender: false` in `useEditor` under any server-rendering framework.** The editor builds a DOM view on construction, so rendering it on the server produces a hydration mismatch.

**Import `BubbleMenu` and `FloatingMenu` from the `/menus` sub-path** — `@tiptap/react/menus` in v3. The root export no longer carries them.

**Give every custom Node a `name`, a `group`, a `parseHTML` and a `renderHTML`.** Schema resolution needs all four; content saved by a node missing `parseHTML` cannot be loaded back.

**Write chained commands as `editor.chain().focus()...run()`.** `.focus()` returns the cursor to the editor before the command applies, and `.run()` is what dispatches the transaction — a chain without it builds a transaction and discards it.

</critical_requirements>

---

**Auto-detection:** TipTap, tiptap, `@tiptap/core`, `@tiptap/react`, `@tiptap/vue-3`, `@tiptap/starter-kit`, `@tiptap/pm`, useEditor, useEditorState, EditorContent, EditorContext, BubbleMenu, FloatingMenu, Node.create, Mark.create, Extension.create, NodeViewWrapper, NodeViewContent, ReactNodeViewRenderer, editor.chain, editor.commands, editor.isActive, mergeAttributes, addKeyboardShortcuts, addInputRules, addPasteRules, addNodeView, addProseMirrorPlugins

**Applies to:**

  • Rich text editors with custom formatting and block types
  • Custom content types — embeds, mentions, callouts, syntax-highlighted code — as extensions
  • Contextual editing UI: bubble menus, floating menus, slash commands
  • Interactive blocks rendered as framework components through node views
  • Automatic formatting through input rules and paste rules
  • Serializing the document to JSON or HTML

**Handled elsewhere:**

  • Everything the editor renders around itself — TipTap is headless, so buttons, popovers, layout and

visual design are settled by whatever owns components and styling

  • Where the document goes after `getJSON()` — the transport and the store are not the editor's

concern

  • Real-time sync between clients — the editor exposes the state to bind and settles none of the

transport

  • Sanitizing HTML before `setContent` — the parser maps what it is given onto the schema and does

not clean it

---

<philosophy>

**Headless.** TipTap provides behaviour, schema and state, and imposes no UI. Every toolbar, menu and control in this skill is ordinary component code reading `editor.isActive(...)` and dispatching commands.

**Everything is an extension**, including paragraphs, bold and undo. So the schema is exactly what you assembled: nothing is present that you did not add, and any built-in can be configured or extended rather than worked around.

**ProseMirror underneath.** The schema system, transaction model and plugin architecture are ProseMirror's, reached through `@tiptap/pm/*`. Where TipTap's API runs out, `addProseMirrorPlugins()` is the escape hatch rather than a rewrite.

**One core, several adapters.** `@tiptap/core` is framework-free; `@tiptap/react` and `@tiptap/vue-3` add hooks and components over the same editor.

</philosophy>

---

<decision_framework>

Which extension type

New content that lives in the document?
├─ Block-level (paragraph, heading, image)?  → Node, group: "block"
├─ Inline element (mention, emoji)?          → Node, group: "inline", inline: true
└─ Formatting over a text range?             → Mark

Behaviour with no schema change?
├─ Keyboard shortcut?                        → Extension + addKeyboardShortcuts
├─ Character count, placeholder, focus?      → Extension
└─ Lower-level control?                      → Extension + addProseMirrorPlugins

How interactive is the node

Just renders HTML?                    → renderHTML alone, no node view
Needs editable child content?         → node view with NodeViewContent inside NodeViewWrapper
Buttons, inputs, live UI?             → node view, contentEditable={false} on the controls

StarterKit or individual extensions

Do you need most of the standard formatting?
├─ YES → StarterKit, disabling what you do no
Read more
Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin

Other skills on agents-inc-skills.