Quick Start

Start with a single editor on a page and the default toolbar. First get typing and formatting working; add uploads, AI, and collaboration later. For framework-specific wrappers (React, Vue, Angular, Svelte, Blazor, ASP.NET, PHP), see Download.

Which setup do you need?

Success means you can type text, select it, and apply bold. Reading HTML is the next step; saving it permanently requires your application’s backend.

Already tried and got stuck? Check setup problems below.

1. Get the editor

Three paths. The CDN needs no install at all and is the quickest way to see the editor running; the other two are what production deployments use.

Option A — Download the licensed bundle

Visit /download and grab the bundle for your framework. Unzip it into your site so the editor lives at /richtexteditor/:

your-site/
├── richtexteditor/
│   ├── rte.js                       ← protected production build (~410 KB)
│   ├── rte_theme_default.css
│   ├── plugins/
│   │   ├── all_plugins.js           ← AI Toolkit, comments, slash, mentions, etc.
│   │   ├── aitoolkit.css
│   │   ├── crdt-engine.min.js       ← Per-node Yjs CRDT (load only if you use collab)
│   │   └── ...
│   └── lang/                        ← optional translations
└── your-page.html

Option B — npm (recommended)

npm install @richscripts/richtexteditor

# or scaffold a complete working example app:
npm create @richscripts/richtexteditor my-app -- --react   # also: --vue, --angular, --svelte

Then import the styles + bundle from your build pipeline:

// Side-effect import attaches `RichTextEditor` to `window`.
import "@richscripts/richtexteditor/richtexteditor/rte.js";
import "@richscripts/richtexteditor/richtexteditor/plugins/all_plugins.js";

// Or via the typed React wrapper (Vue / Angular wrappers shipped too):
import { RichTextEditorComponent } from "@richscripts/richtexteditor/react";

Option C — CDN, nothing to install

jsDelivr and unpkg both mirror the published npm package, so a working editor is two tags in an empty HTML file — no download, no build step, no account. Paste this into a CodePen and it runs:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@richscripts/richtexteditor@2.11.0/richtexteditor/rte_theme_default.min.css" />
<script src="https://cdn.jsdelivr.net/npm/@richscripts/richtexteditor@2.11.0/richtexteditor/rte.js"></script>

<div id="div_editor1">Hello RichTextEditor</div>
<script>
  var editor1 = new RichTextEditor("#div_editor1");
</script>

That gives you the core editor and its toolbar. Add one more tag for the full plugin set — AI Toolkit, comments, slash commands, mentions, layout tables and the rest:

<script src="https://cdn.jsdelivr.net/npm/@richscripts/richtexteditor@2.11.0/richtexteditor/plugins/all_plugins.min.js"></script>

Pin the version. Every path above names @2.11.0 on purpose: a pinned URL is immutable and cached for a year, so your page cannot change under you. @2 resolves to the newest 2.x release, which is useful while evaluating and unwise in production. Swap the host for https://unpkg.com/ and the same paths work there.

Or serve it from our domain. The same files are published at cdn.richtexteditor.com— byte-for-byte the build this site itself runs, cached at Cloudflare’s edge, with no third party between you and us:

<link rel="stylesheet" href="https://cdn.richtexteditor.com/richtexteditor/rte_theme_default.min.css" />
<script src="https://cdn.richtexteditor.com/richtexteditor/rte.js"></script>
<script src="https://cdn.richtexteditor.com/richtexteditor/plugins/all_plugins.min.js"></script>

The trade-off is version pinning, and it runs the other way. These paths carry no version, so they always serve the current release and you cannot hold a page on an older one; browsers are told to re-check every four hours. The jsDelivr URLs above are immutable per version, which is what you want for a build you need to reproduce months from now. Use cdn.richtexteditor.com when you would rather not add a third party to your page, and the pinned jsDelivr URLs when you need the version nailed down.

Two things worth knowing before you ship it. The CDN is a third party serving your page— convenient for trials, prototypes and bug reports, but the self-hosted paths above are what keep the editor entirely inside your own infrastructure, which is the point of a perpetual licence. And a CDN changes how the files reach the browser, not what you are licensed to do with them; see /license.

2. Add the script and create your first editor

<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>

<div id="div_editor1">Hello RichTextEditor</div>
<script>
    var editor = new RichTextEditor("#div_editor1");
</script>

That's a working editor with the default toolbar. Open it in a browser and start typing.

3. Customise the toolbar

Pass a config object as the second argument:

var editor = new RichTextEditor("#div_editor1", {
    toolbar:    "basic",      // "basic" | "full" | "mobile" | "custom"
    height:     "500px",
    showStatistics:  true,    // word / character count in the bottom bar
    showFloatTextToolBar: true
});

For a custom toolbar with explicit groups:

var editor = new RichTextEditor("#div_editor1", {
    toolbar: "custom",
    toolbar_custom:
        "{bold,italic,underline}|" +
        "{insertorderedlist,insertunorderedlist}|" +
        "{insertlink,insertimage}|" +
        "{aiassist,aichat}|" +
        "{undo,redo}"
});

See toolbar & menu items reference for every command name.

4. Read and write content

// Get the current HTML
var html = editor.getHTMLCode();

// Replace the editor's content
editor.setHTMLCode("<p>New content</p>");

// Get plain text (no markup)
var text = editor.getPlainText();

// Get a structured-content JSON document (lossless round-trip with setJSON())
var json = editor.getJSON();
editor.setJSON(json);

5. Submit content with a form

If your editor sits inside a <form>, RichTextEditor automatically writes the editor's HTML into a hidden field that mirrors the editor's container id. Server-side, you read it from the request like any other form field. For dynamic submissions, call editor.getHTMLCode() from your submit handler:

document.getElementById("save").addEventListener("click", function () {
    fetch("/api/save", {
        method:  "POST",
        headers: { "Content-Type": "application/json" },
        body:    JSON.stringify({ html: editor.getHTMLCode() })
    });
});

Having trouble getting started?

npm is not recognized
Install Node.js with npm, reopen your terminal, and check node --version and npm --version. If installation reports an unsupported engine, use a Node version supported by your starter’s dependencies.
The example will not start
Run commands inside the folder containing package.json, after npm install completes. The React starter uses npm run dev; the Angular starter uses npm start. Open the URL printed in the terminal.
The editor is blank or RichTextEditor is not defined
Check the browser Console for the first error and Network for failed script requests. Confirm the runtime URL loads JavaScript, not a 404 or an HTML fallback page. In plain HTML, load the runtime before creating the editor, after its container exists.
The toolbar looks unstyled
Check that the editor theme stylesheet loads successfully. Keep the stylesheet and scripts from the same editor version.
My content disappears after a refresh
Reading HTML does not save it to a database. The /api/save URL above is an example endpoint you must implement; check its response and load the saved HTML when reopening the editor.

Contact support with your framework and editor versions, the command or action that failed, the first error message, and a small reproducible example. Remove API keys, passwords, and private document content before sharing.

6. Pick your next step

Add AI

AI Toolkit

Ask AI from the toolbar, dock the AI Chat panel, queue suggestions in the AI Review drawer. Wire to OpenAI / Anthropic / Azure with one line of DI on the server, or pass a client-side setResolver() callback.

Add real-time collaboration

Per-node Yjs CRDT

Same-paragraph concurrent typing without merge conflicts. Pass textSync: "crdt" to editor.collab.attach() with any Yjs provider you self-host.

Customise everything

Configuration Reference

Every config flag, every toolbar slot, every event name in one searchable page. Defaults live at the top of rte.jsand are intentionally editable so you don't need to rebuild anything.

Wire your back-end

Framework wrappers

Native bindings for React, Vue, Angular, Svelte, Blazor Server, ASP.NET Core, ASP.NET Web Forms, Classic ASP, and PHP. Same editor, idiomatic surface in your stack of choice.

Customise defaults without rebuilding

The top of rte.js is editable plain JavaScript

Every rte.js bundle has an RTE_DefaultConfig block at the top in plain JavaScript, followed by the licensed editor code. Open rte.js in any text editor and change values such as RTE_DefaultConfig.skin, default toolbar, language defaults, upload URLs, etc. — these settings are intentionally kept editable so you can customise behaviour site-wide without re-running any build pipeline.