Plain Text Editing
Click-to-edit text fields for headings, labels, and short content. Renders as a simple contenteditable with ProseMirror under the hood for consistent cursor behavior and undo/redo support.
editable-kit
editable-kit adds inline text, rich text, and image editing to any Svelte app. No admin panels, no CMS — your users edit content right where it lives. Click ‘Edit Page’ above to try it.
Core
Everything you need for inline editing, nothing you don't.
Click-to-edit text fields for headings, labels, and short content. Renders as a simple contenteditable with ProseMirror under the hood for consistent cursor behavior and undo/redo support.
Full rich text editing powered by TipTap — bold, italic, headings, links, lists, and blockquotes. The editor and all extensions are lazy-loaded so they only add to your bundle when editing is active.
Built-in image editor with pan, zoom, and aspect-ratio cropping. Images are exported as optimized WebP via OffscreenCanvas, keeping file sizes small without sacrificing quality.
Guides
Dive deeper into the architecture and patterns behind editable-kit.
Wrap your page in an Editable.Root to enable editing, then use Editable.Data to mark regions of content. Each region exposes snippet helpers — text(), multiline(), rich(), and image() — that replace static markup with live editors when editing is active. The library handles the rest: registering editors, collecting changes on save, and lazy-loading heavy dependencies like TipTap so your initial bundle stays small.
Read more →editable-kit uses a context hierarchy built on Svelte 5 runes. Editable.Root provides global editing state, while each Editable.Data region tracks its own editors in a SvelteMap and coordinates saves through the root context. This means you can nest editable regions freely — a page with cards, a list of posts, a settings panel — and each region manages its own state while the root handles orchestration.
Editable.Data is generic over your data shape. When you pass data of type T, the snippet helpers are constrained to only accept valid property names — text() and multiline() for ProseMirrorJSON fields, image() for ImageState fields. Mistakes are caught at build time, not at runtime. Rename a field and the compiler tells you everywhere it needs updating.