- TypeScript 98.9%
- JavaScript 0.6%
- HTML 0.3%
- CSS 0.2%
|
All checks were successful
CI / ci (push) Successful in 4m49s
Install Playwright system dependencies in CI for the Trixie runner. Track undo and redo availability through editor-local DOM history. Preserve explicit left alignment across block replacement, undo, and redo. Avoid browser-dependent assumptions about disabled controls and native undo grouping. |
||
|---|---|---|
| .forgejo/workflows | ||
| lib | ||
| playground | ||
| test | ||
| .editorconfig | ||
| .gitignore | ||
| .node-version | ||
| CHANGELOG.md | ||
| eslint.config.js | ||
| LICENSE | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.build.json | ||
| tsconfig.consumer.json | ||
| tsconfig.json | ||
| vitest.config.ts | ||
bit-editor
A modular, framework-agnostic rich-text editor for modern browsers.
bit-editor is being designed as a Vanilla TypeScript library with native ESM output. It will provide a small, auditable editor core without a framework runtime dependency, global registration, telemetry, or implicit network access.
Status
The first editing surface is available. It supports paragraphs, configurable semantic headings, soft line breaks, optional inline formatting and text alignment, a modular toolbar, and sanitized clipboard operations while blocking drop and unsupported formatting operations.
Design Goals
- Work consistently on desktop browsers, iPadOS, and Android tablets.
- Keep the editor core independent of Vue, React, and other UI frameworks.
- Make supported document structures and formatting explicitly configurable.
- Apply the same schema rules to input, paste, copy, normalization, and serialization.
- Keep commands, schema extensions, and editing behaviour modular and tree-shakeable.
- Ship native ESM modules and TypeScript declarations without a pre-bundled runtime.
- Maintain 100% line, statement, function, and branch coverage through behaviour-focused tests.
Requirements
Development requires Node.js 24 and pnpm 11.
Install the browser engines used by the DOM behaviour tests once after installing dependencies:
pnpm exec playwright install chromium firefox webkit
Quick Start
<div id="editor-toolbar"></div>
<div id="editor" aria-label="Article content"></div>
import {useEditor} from '@mburchard/bit-editor';
const element = document.querySelector<HTMLElement>('#editor');
const toolbarElement = document.querySelector<HTMLElement>('#editor-toolbar');
if (!element || !toolbarElement) {
throw new TypeError('The editor or toolbar element is missing');
}
const instance = useEditor(element, toolbarElement);
The standard preset matches the playground toolbar without HTML source mode. Import useHtmlEditor from
@mburchard/bit-editor/html when source editing is required. The granular createEditor and createToolbar APIs
remain available for custom schemas and toolbars.
The editor uses the supplied element directly and marks it with data-bit-editor-root. Enter creates a paragraph,
and Shift+Enter creates a soft line break. Pass {enterMode: 'line-break'} to make Enter create a line break as well.
The editor sets the document-wide native paragraph separator to p.
Ordered and unordered lists are enabled by default and support nesting with Tab and Shift+Tab. Pass listTypes to
limit the allowed types or disable lists. Disallowed list markup is converted to paragraphs during sanitization.
H1 through H3 are enabled by default. Pass headingLevels to support any chosen combination of H1 through H6, and
provide matching headings entries to headingSelect when the toolbar should expose a custom set.
When a heading selector is present, it must expose every heading level enabled by the editor. Toolbar creation throws
a TypeError describing missing or unsupported levels when the configurations differ.
Text alignment is opt-in through textAlignments; add matching alignment actions to expose it in the toolbar.
Block indentation is opt-in through indentation; each command step uses a logical 0.5rem margin.
The optional toolbar injects its functional base styles once per document and exposes scoped data attributes and CSS
custom properties for application styling. The application owns the editor's accessible name and visual design.
Undo and redo commands use the browser's native editing history in visual and source mode.
Initial content may be empty, direct text, or configured paragraphs and headings containing text, line breaks, and
configured inline formats.
Call instance.destroy() to remove preset controls and listeners and restore the attributes owned by bit-editor.
Edited content remains in the editor element.
Development
pnpm install
pnpm lint
pnpm typecheck
pnpm test:firefox
pnpm test:webkit
pnpm coverage
pnpm package:check
pnpm playground:check
package:check performs a package dry run, which builds the native ESM package through prepack, then validates it
from a consumer project and checks that an unused package import contributes no runtime code to a browser bundle.
Pure library tests run in Node.js, editing-surface coverage runs in real Chromium, and the same behaviour suite runs
in Firefox and WebKit as compatibility checks.
Playground
The private playground workspace package exercises bit-editor directly from a Vanilla TypeScript and Vite consumer
while keeping Vite and bit-log out of the editor package dependencies and published tarball.
pnpm playground:dev
The command builds bit-editor before starting the playground, so the page consumes the same package exports that an external application would use.
Framework Integration
Framework integrations do not belong to the editor runtime or its Vanilla playground. A separate Vue demonstration will later show how to wrap the Vanilla TypeScript API in a Vue component without adding Vue as a dependency or peer dependency to the editor package.