Standalone visual editor for Unity UI Toolkit UXML and USS. The editor core is browser-first; Tauri 2 provides a thin Windows desktop host for native filesystem operations.
Editing is source-backed: every hierarchy, canvas, and inspector action is a patch against the original UXML/USS bytes, so comments, attribute order, and user formatting survive a round trip.
- Projects — open a directory through the File System Access API in the
browser or the native picker on desktop; enumerate, read, and save
.uxmland.ussfiles with revision checks, external-change watching, and crash recovery. - Canvas — Yoga-backed preview with selection, drag/resize manipulation, and static pseudo-state toggles.
- Hierarchy — reparent, reorder, insert, and delete elements from a
palette of
uxml-preview's renderers. - Inspector — provenance-aware attribute and style authoring that shows which rule a computed value came from and writes to the matching source.
- Source — CodeMirror editing of the same documents, kept in sync with the visual views through one transaction/undo history.
- Diagnostics — parser and renderer warnings surfaced per document.
- Animation of any kind. USS transitions are parsed and preserved but never played; pseudo-state toggles are static.
- Unity 6.3 features. Rendering comes from the vendored
uxml-preview0.5.0 engine invendor/uxml-preview, which is measured against Unity 6000.0.40f1 and has nofilter,aspect-ratio, SVG, 9-slice, or text-outline support. - Controls beyond
VisualElement,Label,Button,Image,ScrollView,Toggle,TextField,IntegerField,FloatField,DropdownField,Slider,SliderInt, andFoldout. Unknown controls stay in the tree, render as fallback boxes, and raise a warning. Everything afterScrollViewis built from Unity's documented element names and USS classes rather than from measurements, so captions, classes, and nesting are right but default sizes and spacing are not; each says so through a diagnostic. - Atomic conditional replacement off Windows. The native
replaceTextAtomicallyreturnsunsupportedon other platforms; the browser host uses its own revision-checked write path.
- Node.js
>=24.15.0 <25, with npm - Rust stable (desktop host)
- Windows: Visual Studio C++ build tools, the Windows SDK, and the WebView2 runtime
- Linux (host development only):
libwebkit2gtk-4.1-dev,libgtk-3-dev,libsoup-3.0-dev,librsvg2-dev,libjavascriptcoregtk-4.1-dev,pkg-config
npm ci
npm run dev # Vite dev server on :1420
npm run typecheck # tsc --noEmit
npm test # Vitest unit and integration suites
npm run test:e2e # Playwright, against the dev server
npm run test:rust # cargo test for the desktop host
npm run check:licenses # dependency license allowlist
npm run build # typecheck + browser production build
npm run tauri:dev
npm run tauri:build # Windows installer and portable artifacts
npm run smoke:packaged # artifact + --version-file checks on the built exe
npm run smoke:packaged:app # Windows: drives the packaged app over WebView2 CDPCI runs the same commands on Linux and repeats the host tests plus a
tauri build --no-bundle on Windows, which is the only platform that exercises
the conditional-replacement implementation.
The packaged executable accepts --open <project-dir> (or a bare directory
argument) to open a project on launch. smoke:packaged:app uses that flag
plus UXML_EDITOR_CDP_PORT — an opt-in WebView2 remote-debugging port the
app honors only when the variable is set — to drive a real
open → save → edit → relaunch cycle against files on disk.
src/core holds the host-agnostic editor: the source patch engine, document
sessions, transactions, stable locators, UXML/USS commands, and the
persistence/recovery layer. src/features holds the panels. src/app wires a
host implementation (BrowserHost, MemoryHost, or the Tauri host in
src-tauri) into the shell.
The preview engine is vendored source, not an npm dependency:
vendor/uxml-preview holds uxml-preview 0.5.0 under
Apache-2.0, with its upstream test suite, its license, and the import recorded
in vendor/uxml-preview/PROVENANCE.md. It
is vendored because Unity 6.3 parity, controls beyond its five renderers, and
transition playback all need engine changes upstream has scoped out. npm test
runs the upstream suite, so engine edits still have to satisfy the measurements
they came from.
It is reachable from exactly one file,
src/core/adapter/UxmlPreviewAdapter.ts; an import-boundary test enforces that,
that the package is absent from dependencies, and that the app's TypeScript
program stays free of Node typings.
Layering and the fidelity model are described in
docs/architecture.md; what the preview can and cannot
reproduce — including which controls are measured versus merely documented —
is in docs/compatibility.md. Decisions are recorded
in docs/adr.
Original code is licensed under Apache-2.0. See LICENSE and
THIRD-PARTY-NOTICES.md.
