---
title: "Add a block or feature"
description: "Agent playbook for adding an own block or feature to @skaile/forge-editor: an ordered checklist where each step links to the tutorial chapter that shows it."
canonical_url: "https://skaile-ai.github.io/forge-editor/ai-agents/extend"
---
# Add a block or feature

> Agent playbook for adding an own block or feature to @skaile/forge-editor: an ordered checklist where each step links to the tutorial chapter that shows it.

Two ways to add a block: **Path A** passes `extensions` and a `commands` transformer to `SimpleEditor` (no feature object); **Path B** ships an `EditorFeature` that composes with any preset. The tutorial builds the same „Hinweis" callout both ways; follow the chapters in order and use this list as the checklist.

1. **Node.** `Node.create` in a Vue-free `node.ts`; `group`, `content`, attributes with `parseHTML`/`renderHTML`, commands and a free shortcut. [Tutorial: own block, path A](https://skaile-ai.github.io/forge-editor/tutorial/own-block-path-a)
2. **Block IDs.** `editorBlock: true` if AI operations, flash/reveal, paste de-duplication or the server ID backfill should reach it. [Tutorial: own block, path A](https://skaile-ai.github.io/forge-editor/tutorial/own-block-path-a)
3. **Abilities.** `abilities` on the node for what is allowed inside; for a custom ability id, grant it through the `abilities` prop (`root`). [Tutorial: own feature, path B](https://skaile-ai.github.io/forge-editor/tutorial/own-feature-path-b)
4. **Markdown.** `renderMarkdown`, `markdownTokenName`, `markdownTokenizer`, `parseMarkdown` with syntax no other stage claims; test the round trip (`getMarkdown()` → `parseBlocks`), including multi-block bodies. [Tutorial: own block, path A](https://skaile-ai.github.io/forge-editor/tutorial/own-block-path-a)
5. **View and CSS.** Node view in a separate `index.ts` (`Node.extend`), stylesheet imported after `core.css`. [Tutorial: own block, path A](https://skaile-ai.github.io/forge-editor/tutorial/own-block-path-a), CSS order: [CSS and UI-provider requirements](https://skaile-ai.github.io/forge-editor/reference/css-and-ui)
6. **Path A.** `extensions` (constant) and the `commands` transformer prop (a command with `slash: {}`), nothing else needed. [Tutorial: own block, path A](https://skaile-ai.github.io/forge-editor/tutorial/own-block-path-a)
7. **Path B.** An `EditorFeature`: `extensions`, then `commands` (one `CommandDef` per command with `toolbar` and/or `slash` placement, `creates`, `ability`) and `toolbarGroups` if you need a new group, `blockActions` with your `ability`, `conversions` with a `custom` target; `requires` for features you depend on. [Tutorial: own feature, path B](https://skaile-ai.github.io/forge-editor/tutorial/own-feature-path-b), every member: [Feature contract](https://skaile-ai.github.io/forge-editor/reference/feature-contract)
8. **Compose.** `defineEditor({ features: [...advancedEditor().features, yourFeature()] })` in setup (`advancedEditor` from `/vue/advanced` or `/react/advanced`); mount with `EditorSurface` and pass `abilities` for custom ability ids; add `blockUiFeature()` to a smaller list when you use hover actions. [Tutorial: compose features](https://skaile-ai.github.io/forge-editor/tutorial/compose-features), [Tutorial: own feature, path B](https://skaile-ai.github.io/forge-editor/tutorial/own-feature-path-b)
9. **Server.** When documents with your block are collaborative, pass `YourNode` in the server's `schema` option (`provideEditorServer({ ports, schema: () => [...advancedSchemaExtensions(), YourNode] })`; the collab server uses it instead of `advancedSchemaExtensions()`), or build `getSchema([...advancedSchemaExtensions(), YourNode])` in your own Hocuspocus server. [Tutorial: backend and collaboration](https://skaile-ai.github.io/forge-editor/tutorial/backend-and-collaboration), [Vue-free schema for servers](https://skaile-ai.github.io/forge-editor/reference/advanced-schema)
10. **AI.** Decide what the model should see (`renderMarkdown`) and write; describe the block in `aiContext.blocks` (`id`, `label`, `description`, `syntax`, `example`, matching your Markdown); `aiContext` is additive, a block id may be described only once; add a `custom` conversion provider if the block should be a `convert` target. [Tutorial: AI](https://skaile-ai.github.io/forge-editor/tutorial/ai), [AI guide](https://skaile-ai.github.io/forge-editor/guides/ai)
11. **Bundle proof.** If you ship the block in a package, add a fixture and a `FIXTURES` entry for `bun run check:editor-entries` ([Dependency rules](https://skaile-ai.github.io/forge-editor/reference/dependency-rules)); `bun run check:editor-composition` covers `defineEditor` validation. [Verify](https://skaile-ai.github.io/forge-editor/ai-agents/verify)

Then check the [invariants](https://skaile-ai.github.io/forge-editor/ai-agents/invariants).


## Sitemap

See the full [sitemap](https://skaile-ai.github.io/forge-editor/sitemap.md) for all pages.
