Skip to content

Svelty Editor

A Svelte 5 wrapper component for Editor.js — built with runes, TypeScript, and lazy-loaded tools.

  • Svelte 5 — uses $props, $state, and $effect runes
  • TypeScript — fully typed props, events, and exports
  • Bring your own tools — install only the Editor.js plugins you need
  • Snippet support — render custom UI around the editor with Svelte 5 snippets
  • Component APIsave(), setReadOnly(), registerTool(), and getManager() via bind:this
  • EditorManager — access the underlying manager class directly for advanced use cases
Terminal window
npm install svelty-editor @editorjs/editorjs

Then install whichever Editor.js tools you want to use:

Terminal window
npm install @editorjs/header @editorjs/list @editorjs/paragraph
PackageBlock type
@editorjs/headerHeadings (H1–H6)
@editorjs/listOrdered / unordered lists
@editorjs/paragraphParagraphs
@editorjs/imageImage blocks
@editorjs/embedEmbedded content (YouTube, etc.)
@editorjs/delimiterVisual dividers
@editorjs/markerInline text highlighting
@editorjs/quoteBlock quotes
@editorjs/tableTables
@editorjs/warningWarning callouts

You can also use any Editor.js plugin — just pass its class in the tools prop.

<script lang="ts">
import { SveltyEditor } from 'svelty-editor';
import Header from '@editorjs/header';
import List from '@editorjs/list';
import Paragraph from '@editorjs/paragraph';
let editor: ReturnType<typeof SveltyEditor>;
async function handleSave() {
const data = await editor.save();
console.log(data);
}
</script>
<SveltyEditor
bind:this={editor}
tools={{
header: { class: Header },
list: { class: List },
paragraph: { class: Paragraph }
}}
placeholder="Start writing..."
/>
<button onclick={handleSave}>Save</button>

SveltyEditor accepts all Editor.js configuration options (except holder, which is managed internally), plus:

PropTypeDescription
toolsRecord<string, EditorTool>Map of tool names to their config (including the class).
dataOutputDataInitial editor content.
placeholderstringPlaceholder text for an empty editor.
autofocusbooleanFocus the editor on mount.
readOnlybooleanStart in read-only mode.
onChange(api, event) => voidCalled when editor content changes.
onReady() => voidCalled when the editor is ready.
classstringCSS class applied to the outer wrapper.
childrenSnippetSvelte 5 snippet rendered above the editor.

Access these via bind:this:

<SveltyEditor bind:this={editor} ... />

Returns the editor content as an OutputData object.

const data = await editor.save();

Toggle read-only mode.

editor.setReadOnly(true);

Dynamically register a tool at runtime. The editor will reinitialize to pick it up.

await editor.registerTool(
'checklist',
() => import('@editorjs/checklist'),
{ inlineToolbar: true }
);

Returns the underlying EditorManager instance for advanced use cases.

const manager = editor.getManager();
const editorjs = manager.getEditor(); // raw Editor.js instance

Each tool entry accepts an EditorTool object:

tools={{
header: {
class: Header,
inlineToolbar: true,
config: {
levels: [1, 2, 3],
defaultLevel: 2
},
shortcut: 'CMD+SHIFT+H'
}
}}
FieldTypeDescription
classTool constructorThe Editor.js tool class.
inlineToolbarboolean | string[]Enable inline toolbar for this block.
configRecord<string, unknown>Tool-specific configuration.
shortcutstringKeyboard shortcut.
tunesstring[]Block tunes to apply.

Render custom UI above the editor content using Svelte 5 snippets:

<SveltyEditor bind:this={editor} tools={...}>
{#snippet children()}
<div class="my-toolbar">
<button onclick={() => editor.save()}>Save</button>
</div>
{/snippet}
</SveltyEditor>
<SveltyEditor
tools={...}
onChange={(api, event) => {
console.log('Content changed:', event);
}}
onReady={() => {
console.log('Editor is ready');
}}
/>
<SveltyEditor
tools={...}
data={{
blocks: [
{ type: 'header', data: { text: 'Hello', level: 2 } },
{ type: 'paragraph', data: { text: 'Some content here.' } }
]
}}
/>

For more control, import EditorManager directly:

import { EditorManager } from 'svelty-editor';
import type { EditorOptions } from 'svelty-editor';

The manager exposes:

  • initialize() — create the editor instance
  • save() — get editor output
  • destroy() — clean up
  • setReadOnly(boolean) — toggle read-only
  • registerTool(name, loader, config?) — add a tool dynamically
  • updateOptions(options) — update editor options
  • getEditor() — access the raw Editor.js instance
  • getInitializedTools() — get loaded tool configs

All types are exported:

import type {
EditorOptions,
EditorTool,
EditorChangeEvent,
I18nConfig,
ToolsLoadMap,
SveltyEditorProps
} from 'svelty-editor';