Skip to content

Global Limits, Common Pitfalls, and Platform Differences ​

Syntax-level pitfalls ​

SymptomCause & fix
Tag renders as blank and prints unknown tagThe tag name is misspelled or it's an unimplemented component. Implemented tags are listed in the section headings on this page

Behavior-level pitfalls ​

SymptomCause & fix
Typing in an input does nothing / the slider won't dragThe controlled component isn't writing back. Write the value back to the signal in onInput / onChange
The input's cursor doesn't blinkThe event pump has fallen asleep. Attach an idle requestAnimationFrame loop
Clicking a button does nothing (pure Go embedding scenario)When embedding with pure Go, script closures need a VM callback bridge; tests must run the full event loop rather than pumping bare
Wrapped text has the wrong height / covers sibling nodesWrapping needs a width constraint: write an explicit width, or provide width via the parent container's stretch
All children of a container with a background pile up in the top-left cornerThat isn't a column/row; a generic box doesn't lay out its children
Rows scrolled out of the viewport are invisible but "seem clickable"That can't happen — scroll's painting and hit testing share the same viewport, by design
Sizes jitter during animationProperty reads should go through the render layer's interpolation; if layout reads the prop's final value and then falls back to the intrinsic size, it jitters. You won't hit this in normal use
Tooltip is slow to appear while the pointer rests stillThe tooltip delay is driven by the event pump waking up; it works normally as long as the app has JS timers or window events, and in the worst case (no wake source at all) it appears at the next event
Table rows are not clickabletable rows are not clickable by default (presentation only). For row interaction attach onRowClick and the component bridges it onto every row
Table/tree does not refresh after changing datacolumns / rows / nodes are materialised into internal rows at first layout. Rebuild the component when data changes (change the prop value to trigger a reactive rebuild); mutating array elements in place will not reach the rows already built
Expanding one tree branch collapsed all the othersThat does not happen — expansion survives rebuilds (keyed by the node's key). But two branches sharing the same key will interfere; keep key unique across the whole tree (it falls back to label when omitted)

Unimplemented components (can be simulated with existing capabilities) ​

WantStatus / workaround
Rich texttext supports wrap / ellipsis; inline mixed styling (bold / colored runs) is not available — assemble with row if needed
Inline video playback (platform video layer)The <video> tag and host contract are implemented (S8): it mounts, receives events, and treats playing / muted / loop / volume as controlled props. Decoding is not in the core — it is delegated to the backend's platform video layer (MF / AVPlayerLayer / SurfaceView), which none of the three desktop backends implement yet ⇒ falls back to a poster / placeholder plus one onError({code:"unsupported"}), with canIUse("video") returning false. Picking / saving / system preview live in gx/media; rationale and backend integration steps are in the decision record

Platform differences at a glance ​

CapabilityWindowsLinux (X11)macOS
Windows & rendering✅✅ (needs real-hardware verification)✅ (cocoa, since 0.6.0)
Input method (IME)✅❌✅
Clipboard✅❌ degraded (reads empty string / write returns false)✅ (NSPasteboard)
Native dialogs✅❌ degraded (confirm returns true, openFile returns null)✅ (alert / confirm / openFile / saveFile)
Fonts✅ static candidates✅ lazy scan of font directories, CJK prioritized✅ scans system font directories (darwin selection adapted)
Native capabilities (battery / network / brightness / settings page)✅ via the win32 host——
Native capabilities (camera / location / photo library / permissions)❌ explicitly missing (reports unsupported)——

Full demo scripts (all under testdata/ in the repo)

Run them from the command line with gox testdata/<name>.js, e.g. gox testdata/menu_demo.js.

  • Elements: button_demo.js, form_demo.js, input_demo.js, search_demo.js, rating_demo.js, textarea_demo.js, multiline_demo.js, select_demo.js, tabs_demo.js, feedback_demo.js, slider_demo.js, progress_demo.js, scroll_demo.js, image_demo.js, video_demo.js, canvas_demo.js, dialog_demo.js, dialog_native_demo.js, menu_demo.js, tooltip_demo.js, tabbar_demo.js
  • Lists & conditionals: view_demo.js, view_demo2.js, list_demo.js, vlist_demo.js, condrender_demo.js, resource_demo.js
  • Data display: table_demo.js, tree_demo.js
  • Layout & styling: grid_demo.js, elastic_layout_demo.js, model_demo.js, jsx_demo.js
  • Interaction & animation: events_demo.js, focus_demo.js, hover_demo.js, transition_demo.js, resize_demo.js, clipboard_demo.js, ime_demo.js
  • Module capabilities: router_demo.js (+ the lazy-loaded module router_page_detail.js), router_window_demo.js, routing_demo.js, multiwindow_demo.js, storage_demo.js, dev_panel_demo.js, native_demo.js, counter_demo.js, rx_demo.js, kit_demo.js, gui_demo.js, http_demo.js
  • Runtime & tutorial walkthroughs: demo.js, acceptance.js, tutorial_util.js, tutorial_api.js, tutorial_modules.js, tutorial_gui.js, tutorial_router.js

There's also routing_demo.js, a "userland routing" implementation that doesn't depend on gx/router (one signal + a page table) — useful as a reference for small utilities with three pages or fewer.