News

Building a text editor in the browser: canvas vs contenteditable vs textarea

A developer's journey building a minimal browser-based text editor reveals the performance and accessibility tradeoffs between canvas rendering, contenteditable, and textarea approaches.

September 2, 2026· 2 min read· Source: dbushell.com
Building a text editor in the browser: canvas vs contenteditable vs textarea

David Bushell, fed up with the state of modern software, decided to build his own text editor in the browser. His experiments compare three rendering approaches: <canvas>, contenteditable, and <textarea>. The results offer practical lessons for anyone building code editors or rich text inputs.

Canvas: full control, no accessibility

The first prototype renders everything on a <canvas> element. It supports cursor positioning, arrow key movement, line highlighting, and text input. But canvas gives nothing for free: no text selection, no undo/redo, no multi-line paste, and no overflow scrolling. Bushell hacked scrolling by using a hidden native overflow element to drive render offsets, but the fundamental problem remains: canvas is entirely inaccessible to screen readers and assistive tech.

Contenteditable: free accessibility, performance quirks

The second approach uses contenteditable="plaintext-only" inside a scrollable div. This brings native text selection, undo history, and accessibility for free. The Selection API provides metrics for a custom cursor, and ::selection can be styled. However, performance degrades unpredictably beyond a certain character count, with Chromium worse than WebKit and Firefox.

Textarea: the performance winner

The final prototype uses a <textarea>, which turns out to be far more performant for longer text. The tradeoff: textareas can't use CSS ::highlight, so syntax highlighting requires a third layer of divs. Bushell used MicroLighter for visible lines, but notes that too many CSS highlights cause performance issues. He suggests Tree-sitter for generating highlights only for visible lines, and mentions the inverse sticky technique for virtualized scrolling.

Key takeaways

Bushell's demos are unoptimized and not fully accessible, but they prove a point: starting from a losing position like canvas is a nightmare. He's filing the project away for a rainy day, but the exploration highlights the tradeoffs every web-based editor faces.

He also warns about UTF-16 code unit bugs with emoji and other multi-byte characters, recommending Intl.Segmenter for grapheme-aware string handling.

Canvas gives me nothing for free. Amongst many desirable features, I'm missing: text selection, undo/redo history, multi-line paste, overflow scrolling.
Manul X Editorial
Comparison of rendering approaches for a browser-based text editor
At a glance
FeatureCanvasContenteditableTextarea
Text selectionManual implementationNativeNative
Undo/redoManual implementationNativeNative
AccessibilityNoneGoodGood
Performance (long text)GoodDegrades unpredictablyBest
Syntax highlightingManual drawingCSS ::highlightRequires overlay layer
Overflow scrollingManual implementationNativeNative