IME & composition

Input Method Editors (CJK, Vietnamese, etc.) interact with the DOM first. Your Rust model must follow—not replace—the composition session.

Overview

In WASM you do not “implement IME” for web: the OS/IME draws the candidate window and inserts text through the browser’s editing pipeline. Your integration work is event ordering, commit boundaries, and keeping one source of truth during an unfinished composition.

This site’s scenarios on composition, beforeinput, and mobile keyboards apply equally when the backing model is Rust.

The browser owns IME

Calls across the JS↔WASM boundary should not assume you can sample the “final character” on every keydown: during composition, partial text is provisional. Pushing provisional state into Rust on every compositionupdate can work but increases copies and race risk with layout.

Treat compositionend (and equivalent commit signals) as the primary point to commit stable text into your Rust model—unless you have a deliberate streaming design and handle cancellation.

Composition lifecycle

  • compositionstart — mark an “IME session” in your controller; pause structural merges that assume committed text.
  • compositionupdate — DOM shows intermediate glyphs; optional lightweight mirror into WASM for preview features.
  • compositionend — commit; reconcile selection offsets in UTF-8/UTF-16 aware code (JS strings are UTF-16; Rust String is UTF-8—index mismatches are a classic bug).

Pair with beforeinput where available; cancellation semantics differ by browser—see Editor → Input handling.

Syncing a Rust model

Practical strategies:

  1. DOM truth during composition: WASM holds structural doc; JS keeps ephemeral composition text in the DOM until commit—then send one patch across the boundary.
  2. Op log from committed input only: WASM applies operations for committed codepoints; composition preview stays out of CRDT until commit (simpler for Yjs/Yrs interop).
  3. Full mirror: stream updates—only if you measure boundary cost and handle rollback on cancel.

Mobile & platform variance

Mobile keyboards differ in when composition events fire, how backspace behaves in Hangul/Japanese, and how WebView wrappers behave. Your WASM core cannot abstract that away—you need the same empirical testing as any web editor.

Related: Editor → Mobile support.