Editors

The rich text editor writes everything a document needs — headings, bold to strikethrough, colour, links, bulleted, numbered and check lists, quotes, code blocks, tables, images and dividers — from a toolbar, a menu that opens on /, or Markdown typed as you go. People are mentioned with @, passages carry comments with replies, and with tracked changes on every edit is kept for someone to accept or reject.

Nothing is loaded from anywhere. Everything that reaches the document — typed, pasted from Word or Google Docs, dropped, or set from code — passes one sanitiser, and the document comes out as HTML, Markdown, plain text or JSON. In a <form> it is a field like any other.

A release note, under review

Ann has left a comment and suggested two changes. Open the comments to reply or resolve; accept or reject the changes one at a time or all at once. Switch Track changes on and your own edits are kept the same way, in your name.

Accept all changes Reject all changes

Version 4 is here

This update brings three new features to the app: saved views, a dark theme and faster search. Every one of them works on phones, tablets and desktops.

What stays the same

  • Nothing is sent anywhere: almost everything happens in the page.
  • Ten themes, right-to-left, and a keyboard route to everything.
  • Write the note
  • Have it reviewed
Keyboard: Ctrl+B, I and U as usual, Ctrl+K for a link, / at the start of a line for any block, and Alt+F10 to reach the toolbar, whose buttons are one Tab stop moved through with the arrow keys.
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-rich-text-editor id="ed-review" label="Release note" author="You" tracking style="inline-size: 100%; --bmx-rich-text-editor-min-height: 18rem; --bmx-rich-text-editor-max-height: 30rem">
  <h2>Version 4 is here</h2>
  <p>This update brings <span class="bmx-comment" data-bmx-comment="c1">three new features</span> to the app: saved views, a dark theme and faster search. Every one of them works on <ins data-author="Ann Lee" data-time="2026-10-03T09:12:00Z" data-change="t1">phones, tablets and </ins>desktops.</p>
  <h3>What stays the same</h3>
  <ul>
    <li>Nothing is sent anywhere: <del data-author="Ann Lee" data-time="2026-10-03T09:14:00Z" data-change="t2">almost </del>everything happens in the page.</li>
    <li>Ten themes, right-to-left, and a keyboard route to everything.</li>
  </ul>
  <ul data-type="checklist">
    <li data-checked="true">Write the note</li>
    <li data-checked="false">Have it reviewed</li>
  </ul>
</bmx-rich-text-editor>

HTML, Markdown, text or JSON

Type Markdown as you go — # for a heading, - for a list, **bold**, `code`, > for a quote — and see the document come out in the form you choose. Load Markdown back in with the button.

HTML Markdown Text JSON

                Load a Markdown sample
              
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-rich-text-editor id="ed-out" label="Notes" placeholder="Type here: # heading, - list, **bold**…" style="--bmx-rich-text-editor-min-height: 16rem"></bmx-rich-text-editor>

Mentions, and a toolbar only when needed

A comment box: the toolbar appears over selected text, @ finds people from your own list (here, looked up as you type, as a server would), and the page hears who was mentioned.

Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-rich-text-editor id="ed-comment" label="Comment" toolbar-mode="bubble" placeholder="Write a comment. Type @ to mention someone." status-bar="false" style="inline-size: 100%; max-inline-size: 40rem; --bmx-rich-text-editor-min-height: 6rem"></bmx-rich-text-editor>

Clean paste

What Word puts on the clipboard is a page of styles, conditional comments and empty paragraphs. Load it and see what is kept: the headings, emphasis, lists and table, and nothing else. Anything that could run — a script, an event handler, a javascript: link — never reaches the page.

Load a pasted Word document Load HTML that tries to run a script
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-rich-text-editor id="ed-paste" label="Pasted document" style="inline-size: 100%; --bmx-rich-text-editor-min-height: 12rem"></bmx-rich-text-editor>

In a form

With a name the editor is a form field: it is sent as HTML, it can be required, and it can stop at a number of characters.

Send
Get the code
<script src="/assets/bmx-components.min.js"></script>

<bmx-rich-text-editor name="description" label="Describe the problem" required max-length="400" toolbar="minimal" style="--bmx-rich-text-editor-min-height: 7rem"></bmx-rich-text-editor>