The hard parts
A canvas is easy. An application platform is not.
Drawing controls was never the difficult part. The work is in the
behaviour users notice only when it is missing: editing, selection,
international text, accessibility, native input, and state that
survives real application use.
Editing
IME, clipboard, and password managers
Browser editor mirrors let canvas-rendered TextInput and TextArea controls cooperate with composition, autocorrect, platform clipboard conventions, forms, and password-manager extensions.
Global text
CJK and emoji without permanent tofu
HarfBuzz and ICU shape global scripts while incremental font fallback detects missing glyphs, loads only required coverage, and keeps live text stable as new fonts arrive.
Selection
Selection that crosses boundaries
Mouse drag, reverse selection, cross-node ranges, touch teardrops, handle crossover, context menus, copy, and viewport auto-scroll share one retained selection model.
Accessibility
Pixels are not the semantic tree
EffinDOM projects retained semantics through DOM and ARIA on the web, NSAccessibility on macOS, Microsoft UI Automation on Windows, and AT-SPI on Linux.
TextArea
Fast paths without behavioural forks
Visible-line processing, incremental edits, fixed line heights, monospaced metrics, wrapping, and static-content reuse reduce work while preserving identical Unicode, caret, hit-testing, and selection behaviour.
Native feel
Input follows the host platform
Native trackpad momentum, wheel behaviour, keyboard conventions, multi-click timing, window resizing, system themes, accent colours, and platform context menus are handled by host adapters rather than approximated globally.
Lifecycle
Retained state stays retained
Control identity preserves focus, text, selection, scroll position, overlays, and subscriptions. Browser history can restore named retained state instead of reconstructing a blank page.
Delivery
Fonts and runtimes load without freezing the app
Mandatory runtime assets expose bounded startup progress. Optional script coverage and page fonts load asynchronously, update retained content when ready, and do not block an already usable application.
Host services
Typed access beyond the UI runtime
Applications declare their own host-service boundary and generate strongly typed SDK bindings. Browser or platform code implements the capability without leaking bridge calls, raw pointers, or transport details into application UI.
Workers
Background work without blocking interaction
FUI workers run computation outside the application UI thread with generated message contracts, progress reporting, cooperative yields, cancellation, and an explicit allowlist of host services available inside the worker.