Try it
Click the + button or press Tab to add new blocks. Available types: paragraph, heading, list, checklist, table, quote, code, warning, image, delimiter. JSON output updates live.

JSON Output 0 blocks

Setup

typescript
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
import Checklist from '@editorjs/checklist';
import Table from '@editorjs/table';
import Warning from '@editorjs/warning';
import Image from '@editorjs/image';

const editor = new EditorJS({
  holder: 'editor',
  tools: {
    header: { class: Header, config: { levels: [1, 2, 3] } },
    list: { class: List },
    checklist: { class: Checklist },
    table: { class: Table },
    warning: { class: Warning },
    image: { class: Image, config: {
      uploader: { uploadByUrl(url) { /* ... */ } }
    }}
  }
});

// Save to JSON
const data = await editor.save();

Available Block Types

Paragraph

Default text block with inline formatting (bold, italic, links).

Header

Headings H1-H6 with configurable levels.

List

Ordered and unordered lists with nesting.

Checklist

Interactive task list with checkboxes.

Table

Editable tables with configurable rows/columns.

Quote

Blockquote with text and caption fields.

Code

Code block with monospace font.

Warning

Warning/alert block with title and message.

Image

Image block with URL input and caption.

Delimiter

Visual separator between content sections.

Custom Block Plugin

Creating a custom block type is straightforward. Each plugin implements render(), save(), and optionally validate():

javascript
class MyCustomTool {
  static get toolbox() {
    return {
      title: 'My Block',
      icon: '<svg>...</svg>'
    };
  }
  
  constructor({ data }) {
    this.data = data;
  }
  
  render() {
    const div = document.createElement('div');
    div.contentEditable = true;
    div.innerHTML = this.data.text || '';
    this.element = div;
    return div;
  }
  
  save(blockContent) {
    return {
      text: blockContent.innerHTML
    };
  }
  
  validate(savedData) {
    return savedData.text.trim() !== '';
  }
}

Strengths

  • Simple, clean JSON output
  • Easy to create custom block types
  • Notion-like block UX
  • Framework-agnostic
  • Lightweight and fast

Weaknesses

  • Limited inline formatting options
  • No collaboration support
  • Smaller ecosystem than ProseMirror/Tiptap
  • Less sophisticated document model
  • No markdown support