Vanilla JS

    Vanilla JavaScript Rich Text Editor

    Scribe Editor is a pure JavaScript WYSIWYG editor with zero framework requirements. Under 50KB, no dependencies, works via CDN or npm, and a direct API — editor.bold() instead of execCommand('Bold').

    $npm install scribejs-editor
    < 50KB
    Gzipped bundle
    0
    Dependencies
    CDN
    No build needed

    Why Scribe for Vanilla JS?

    Zero framework requirements

    Works with plain HTML, Alpine.js, HTMX, jQuery, or any setup that touches the DOM. No build tool required for CDN usage.

    The simplest API possible

    editor.bold(), editor.italic(), editor.getHTML(). No execCommand, no command strings, no configuration objects required.

    ESM & CDN ready

    Import via npm for bundled projects or load directly from a CDN via a script type="module" tag. No build step needed.

    Safe by default

    Built-in XSS sanitization and safe paste from Word and Google Docs. No extra DOMPurify or sanitize-html needed.

    Basic Setup (npm)

    Initialize on any selector or DOM element. The floating toolbar appears automatically on text selection.

    import { Scribe } from 'scribejs-editor';
    import 'scribejs-editor/dist/scribe.css';
    
    // One line — works on any element
    const editor = Scribe.init('#editor', {
      placeholder: 'Start writing...',
      toolbar: 'floating',   // floating selection toolbar
      onChange: (html) => {
        document.querySelector('#output').innerHTML = html;
      },
    });
    
    // Direct, readable API
    editor.bold();
    editor.italic();
    editor.heading(2);
    editor.link('https://example.com');
    
    // Get and set HTML
    const html = editor.getHTML();
    editor.setHTML('<p>New content</p>');

    Custom Toolbar

    Disable the built-in toolbar and wire your own buttons. Listen to formatChange events to keep toolbar state in sync.

    import { Scribe } from 'scribejs-editor';
    
    const editor = Scribe.init('#editor', { toolbar: 'none' });
    
    // Wire your own toolbar buttons
    document.querySelector('#btn-bold').addEventListener('click', () => editor.bold());
    document.querySelector('#btn-italic').addEventListener('click', () => editor.italic());
    document.querySelector('#btn-h2').addEventListener('click', () => editor.heading(2));
    document.querySelector('#btn-link').addEventListener('click', () => {
      const url = prompt('Enter URL:');
      if (url) editor.link(url);
    });
    
    // Highlight active formats in your toolbar
    editor.on('formatChange', ({ current }) => {
      document.querySelector('#btn-bold').classList.toggle('active', !!current?.bold);
      document.querySelector('#btn-italic').classList.toggle('active', !!current?.italic);
    });
    
    // Save content
    document.querySelector('#btn-save').addEventListener('click', () => {
      const html = editor.getHTML();
      fetch('/api/save', { method: 'POST', body: JSON.stringify({ html }) });
    });

    CDN Usage (no build step)

    Load Scribe directly from a CDN with a <script type="module"> tag. No npm, no webpack, no bundler required.

    <!DOCTYPE html>
    <html>
    <head>
      <link rel="stylesheet" href="https://unpkg.com/scribejs-editor/dist/scribe.css" />
    </head>
    <body>
      <div id="editor"><p>Start writing...</p></div>
    
      <script type="module">
        import { Scribe } from 'https://unpkg.com/scribejs-editor/dist/scribe.esm.js';
    
        const editor = Scribe.init('#editor', {
          toolbar: 'floating',
          placeholder: 'Write something...',
        });
    
        // Immediately available — no build step required
        window.editor = editor;
      </script>
    </body>
    </html>

    Everything included

    Bold, italic, underline, strikethrough
    Headings H1–H6
    Ordered & unordered lists
    Links with inline editing
    Floating toolbar on text selection
    Fixed toolbar mode
    Paste safe from Word & Google Docs
    Built-in XSS sanitization
    Iframe editing support
    Plugin system for extensibility
    Full TypeScript types included
    MIT license — free forever

    No framework? No problem.

    Scribe is the modern replacement for TinyMCE and Jodit in vanilla JS projects. 8× smaller, cleaner API, MIT licensed, no key required.

    Vanilla JS + Scribe — common questions

    What is the best vanilla JavaScript rich text editor?

    Scribe Editor is one of the best pure JavaScript WYSIWYG editors. It has zero runtime dependencies, is under 50KB gzipped, works with a simple editor.bold() API instead of execCommand, includes a floating toolbar, and has built-in XSS sanitization. It can be loaded via CDN (no build step) or installed via npm.

    Can I use Scribe Editor without a JavaScript framework?

    Yes. Scribe Editor is completely framework-agnostic. Call Scribe.init('#editor') on any DOM element and it works immediately. It integrates well with Alpine.js, HTMX, jQuery, or plain HTML pages with no build configuration required when loaded via CDN.

    Can I load Scribe Editor from a CDN without npm?

    Yes. Use a script type='module' tag to import Scribe from a CDN like unpkg or jsDelivr. No npm, no webpack, no build step — just an HTML file and a script tag. This is ideal for quick prototypes, CMS integrations, or server-rendered pages.

    Is Scribe a replacement for TinyMCE or Jodit in vanilla JS projects?

    Yes. Scribe is under 50KB compared to TinyMCE's 400KB and Jodit's 300KB. It has a simpler modern API (editor.bold() vs execCommand), a floating inline toolbar instead of a fixed desktop-style toolbar, and is fully free under MIT with no license keys required.