feather-editor-vue

A lightweight, zero-dependency rich text editor with clean Feather icons. Framework-agnostic, headless by design.
811
Install
npm install feather-editor-vue
Latest Version:1.2.7
Vue:3
License:MIT
Last Updated:Sep 18, 2026
Links: npm
Maintainer: zin-00

πŸͺΆ Feather Editor

The most lightweight rich text editor for Vue 3 β€” zero dependencies, headless, modular, and fast.

npm version Vue 3 License: MIT Zero dependencies

Getting Started Β· Vue 3 Integration Β· API Docs Β· Configuration Β· Installation Guide


✦ Why Feather Editor?

Most rich text editors are either too heavy (ProseMirror, Slate) or too opinionated (Quill). Feather Editor is the most lightweight rich text editor for Vue 3 β€” a zero-dependency, headless WYSIWYG editor that provides absolute control without the bloat.

  • πŸͺΆ Ultra-Lightweight β€” zero runtime dependencies, pure vanilla JS core, minimal bundle footprint
  • πŸ’š Dedicated Vue 3 Support β€” direct root import of FeatherEditor component and useFeather composable
  • πŸŽ› Config-Driven β€” enable/disable every block, mark, and plugin from a single feather.config.js
  • 🎨 Headless by Design β€” 100% styled via CSS custom properties (styles/feather.css)
  • πŸ”Œ Extensible Architecture β€” add custom blocks, marks, and plugins with plain JavaScript objects
  • πŸ“„ Paper Sizing & Print-Ready β€” built-in A4, Letter, Legal, A5, and fluid canvas formats with clean PDF printing
  • πŸ”’ Security-First β€” sanitized paste, blocked javascript: URLs, safe HTML output

πŸ“¦ Installation

# npm
npm install feather-editor-vue

# yarn
yarn add feather-editor-vue

# pnpm
pnpm add feather-editor-vue

Import the stylesheet once in your app entry point (e.g. main.js):

import 'feather-editor-vue/styles';

⚑ Vue 3 Quick Start

Component (FeatherEditor)

<script setup>
import { ref } from 'vue';
import { FeatherEditor, StarterKit } from 'feather-editor-vue';
import 'feather-editor-vue/styles';

const content = ref('<p>Hello from Feather Editor in Vue 3!</p>');

function handleChange(html) {
  content.value = html;
}
</script>

<template>
  <FeatherEditor
    :extensions="StarterKit"
    :content="content"
    placeholder="Start typing your document…"
    @change="handleChange"
  />
</template>

Composable (useFeather)

<script setup>
import { useFeather, StarterKit } from 'feather-editor-vue';
import 'feather-editor-vue/styles';

const { el, editor, getHtml, setHtml, cmd, focus } = useFeather({
  extensions: StarterKit,
  content: '<p>Custom canvas layout</p>',
  onChange: (html) => console.log(html),
});
</script>

<template>
  <div class="custom-editor-layout">
    <div class="toolbar">
      <button @click="cmd('toggleBold')">Bold</button>
      <button @click="cmd('toggleItalic')">Italic</button>
      <button @click="cmd('setHeading', 2)">H2</button>
    </div>
    <div ref="el" class="editor-mount" />
  </div>
</template>

Vanilla JS (if needed)

import { createFromConfig } from 'feather-editor';
import config from './feather.config.js';
import 'feather-editor/styles';

const editor = createFromConfig('#app', config, {
  content: '<p>Start writing…</p>',
  onChange(html) { console.log(html); },
});

✨ Features

🧱 Block Types

Block Tag Slash Command
Paragraph <p> β€”
Heading <h1> – <h3> /h1 /h2 /h3
Bullet List <ul> /bullet
Ordered List <ol> /ordered
Blockquote <blockquote> /quote
Code Block <pre><code> /code
Horizontal Rule <hr> /divider
Callout custom <div> /callout
Task List <ul data-type> /task
Video Embed <figure> iframe /video
Image <figure><img> /image
Table <table> /table

✍️ Inline Marks

Bold Β· Italic Β· Underline Β· Strikethrough Β· Inline Code Β· Link Β· Superscript Β· Subscript Β· Font Size Β· Font Family Β· Text Color Β· Text Background Β· Highlight

πŸŽ› Formatting

Text Alignment Β· Line Height Β· Indent Β· Outdent Β· Clear Format

πŸ”Œ Plugins

Plugin Trigger Description
Markdown Shortcuts # > - etc. Converts Markdown syntax on the fly
Find & Replace ⌘F / Ctrl+F Floating panel with regex and case match
Drag to Reorder Drag handle β Ώ Reorder any block smoothly by dragging
Format Painter Toolbar πŸ–Œ Copy & paste formatting between selections
Emoji & Icons Toolbar πŸ™‚ Β· :shortcode: Insert emojis inline at the caret or block callouts

πŸ“€ Export & Import

editor.getHtml()          // β†’ sanitized HTML string
editor.setHtml('<p>…</p>')// ← replace content from HTML
editor.getText()          // β†’ plain text string
editor.getMarkdown()      // β†’ Markdown string
editor.setMarkdown(md)    // ← replace content from Markdown
editor.insertMarkdown(md) // ← insert Markdown at caret
editor.getJSON()          // β†’ portable JSON document
editor.setJSON(doc)       // ← replace content from JSON
editor.print()            // β†’ opens clean print dialog (paper formats supported)

βš™οΈ Configuration

All features are toggled from feather.config.js. A change here automatically updates the toolbar, bubble menu, slash menu, and keyboard shortcuts β€” no other files need editing.

// feather.config.js
const config = {

  blocks: {
    paragraph:      true,
    heading:        true,   // H1–H3
    bulletList:     true,
    orderedList:    true,
    blockquote:     true,
    codeBlock:      true,
    horizontalRule: true,
    callout:        true,
    taskList:       true,
    videoEmbed:     true,
    image:          true,
    table:          true,
  },

  marks: {
    bold:           true,   // ⌘B
    italic:         true,   // ⌘I
    underline:      true,   // ⌘U
    strike:         true,   // βŒ˜β‡§S
    code:           true,   // ⌘E
    link:           true,   // ⌘K
    superscript:    true,
    subscript:      true,
    fontSize:       true,
    fontFamily:     true,
    textColor:      true,
    textBackground: true,
    highlight:      true,
  },

  formatting: {
    textAlign:      true,
    lineHeight:     true,
    indent:         true,
    outdent:        true,
    clearFormat:    true,
  },

  plugins: {
    markdownShortcuts: true,
    findReplace:       true,
    dragReorder:       true,
    formatPainter:     true,
    emoji:             true,
  },

  toolbar: {
    enabled: true,
    items: [
      'bold', 'italic', 'underline', 'strike', '|',
      'heading', 'bulletList', 'orderedList', '|',
      'link', 'image', 'table', 'emoji', '|',
      'clearFormat', 'formatPainter',
    ],
  },

  bubbleMenu: {
    enabled: true,
    items: ['bold', 'italic', 'underline', 'strike', '|', 'link'],
  },

  editor: {
    placeholder: "Write something, or type '/' for commands…",
    spellcheck:  true,
    autofocus:   false,
    readOnly:    false,
    attribution: true,   // "Made with Feather" credit; set false to remove
  },

  history: {
    enabled:  true,
    maxSteps: 100,
  },
};

export default config;

πŸ“– API

Content & Inspection

editor.getHtml()            // β†’ HTML string
editor.setHtml('<p>…</p>') // set content
editor.getText()            // β†’ plain text
editor.getMarkdown()        // β†’ Markdown string
editor.isEmpty()            // β†’ boolean

Commands

editor.cmd('toggleBold')
editor.cmd('setTextColor', '#ef4444')
editor.cmd('insertBlock', 'callout')

// Chainable API
editor.chain().toggleBold().toggleItalic().run()

State & Lifecycle

editor.focus()
editor.blur()
editor.enable()
editor.disable()
editor.isActive('bold')    // β†’ boolean
editor.destroy()

Events

editor.events.on('change',          ({ html }) => { … })
editor.events.on('selectionchange', ({ editor }) => { … })
editor.events.on('keydown',         ({ event }) => { … })
editor.events.on('paste',           ({ editor }) => { … })

⌨️ Keyboard Shortcuts

Mac Windows / Linux Action
⌘B Ctrl+B Bold
⌘I Ctrl+I Italic
⌘U Ctrl+U Underline
βŒ˜β‡§S Ctrl+Shift+S Strikethrough
⌘E Ctrl+E Inline code
⌘K Ctrl+K Insert / edit link
⌘Z Ctrl+Z Undo
βŒ˜β‡§Z Ctrl+Shift+Z Redo
⌘F Ctrl+F Find & Replace
/ / Slash command menu

πŸ“ Markdown Shortcuts

Type at the start of a line followed by Space:

Input Result
# Heading 1
## Heading 2
### Heading 3
- or * Bullet list
1. Ordered list
> Blockquote
``` Code block
--- Horizontal rule

Inline marks (wrap text):

Input Result
**text** Bold
*text* Italic
`code` Code
~~text~~ Strikethrough

🎨 Theming

All colours, sizes, and typography are CSS custom properties defined in styles/feather.css. Override them on :root:

:root {
  --feather-bg:                 #ffffff;
  --feather-fg:                 #09090b;
  --feather-border:             #e4e4e7;
  --feather-primary:            #18181b;
  --feather-muted:              #f4f4f5;
  --feather-muted-fg:           #71717a;
  --feather-accent:             #f4f4f5;
  --feather-radius:             6px;
  --feather-font-family:        'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --feather-font-mono:          'JetBrains Mono', ui-monospace, monospace;
}

Dark mode β€” add data-theme="dark" to <html> or any ancestor container:

document.documentElement.dataset.theme = 'dark';

πŸ”Œ Writing Extensions

Extensions can declare a manifest for ordering and validation: dependsOn, conflictsWith, version, and lazy: () => import('…'). Register at runtime with editor.use(ext).

export const MyExt = {
  name: 'myExt', type: 'plugin', version: '1.0.0',
  dependsOn: ['link'], conflictsWith: ['otherExt'],
  commands(editor) { return { /* … */ }; },
};
editor.use(MyExt);

πŸ—‚ Project Structure

feather-editor/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/                  ← Editor, Schema, Commands, EventBus, History, Selection
β”‚   β”œβ”€β”€ extensions/            ← blocks, marks, formatting, plugins
β”‚   β”œβ”€β”€ ui/                    ← Toolbar, BubbleMenu, SlashMenu, PresenceBar
β”‚   β”œβ”€β”€ utils/                 ← dom, html (sanitizer), markdown, json
β”‚   └── createFromConfig.js    ← factory for feather.config.js
β”œβ”€β”€ adapters/
β”‚   └── vue/                   ← useFeather composable + FeatherEditor component
β”œβ”€β”€ docs/                      ← guides and documentation
β”œβ”€β”€ styles/
β”‚   └── feather.css            ← core theme and paper canvas styles
β”œβ”€β”€ feather.config.js          ← feature flags and configuration
└── package.json

πŸ”’ Security

Security is foundational to Feather Editor. Read our Security Policy for details on HTML sanitization, URL validation, and reporting vulnerabilities.


πŸ“„ License

MIT Β© Feather

Feather Editor is free and MIT-licensed β€” use it anywhere, commercially too. By default, the editor displays a subtle β€œMade with Feather” credit; you can remove it anytime with attribution: false in feather.config.js.

Related Packages

@bloklabs/vue

Vue block editor β€” official Vue 3 bindings for Blok, the headless Notion-like ri...

5,341 43
@richkitjs/vue

Vue 3 bindings for RichKit: useEditor composable, EditorContent component and pr...

484 0
stilo-editor

A complete rich text editor. Everything included, ready in minutes. Open-source...

234 2
@xproeditor/vue

Notion-like block editor for Vue 3 β€” supports a sticky format toolbar and/or a f...

1,516 1

Version History

Version Released Vue License
1.2.7 >=3.2 MIT
1.2.5 >=3.2 MIT
1.2.4 >=3.2 MIT
1.2.3 >=3.2 MIT
1.2.2 >=3.2 MIT