<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Rux</title>
    <subtitle>A pure-Rust, web-flavored UI language that renders natively on the GPU — no browser, no webview.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://aine-dickson.github.io/rux/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://aine-dickson.github.io/rux"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-20T00:00:00+00:00</updated>
    <id>https://aine-dickson.github.io/rux/atom.xml</id>
    <entry xml:lang="en">
        <title>Rux v0.2.0 — selection, scrollbars, and a lot of CSS</title>
        <published>2026-07-20T00:00:00+00:00</published>
        <updated>2026-07-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://aine-dickson.github.io/rux/blog/v0-2-0/"/>
        <id>https://aine-dickson.github.io/rux/blog/v0-2-0/</id>
        
        <content type="html" xml:base="https://aine-dickson.github.io/rux/blog/v0-2-0/">&lt;p&gt;v0.1 could open a window and edit a field. v0.2 is about making that field feel
like a field — and about closing the gap between &quot;valid CSS&quot; and &quot;CSS that does
something.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Four things landed: &lt;strong&gt;text selection + clipboard&lt;&#x2F;strong&gt;, &lt;strong&gt;the last two input types&lt;&#x2F;strong&gt;,
&lt;strong&gt;scrolling polish&lt;&#x2F;strong&gt;, and &lt;strong&gt;a serious CSS push&lt;&#x2F;strong&gt;. 74 tests pass, and every item
below was driven in the window before it was called done.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;text-selection-and-the-clipboard&quot;&gt;Text selection and the clipboard&lt;&#x2F;h2&gt;
&lt;p&gt;A focused input now has a selection, not just a caret.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Drag&lt;&#x2F;strong&gt; across text to select it; &lt;strong&gt;double-click&lt;&#x2F;strong&gt; selects a word.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Shift&lt;&#x2F;strong&gt; + any movement (arrows, Home&#x2F;End, Up&#x2F;Down in a textarea) extends from
the anchor; the same movement without Shift collapses.&lt;&#x2F;li&gt;
&lt;li&gt;Typing, pasting, Backspace and Delete &lt;strong&gt;replace&lt;&#x2F;strong&gt; what&#x27;s selected.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl+A &#x2F; C &#x2F; X &#x2F; V&lt;&#x2F;strong&gt; against the real system clipboard, via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;1Password&#x2F;arboard&quot;&gt;arboard&lt;&#x2F;a&gt;. Paste
three lines into a single-line input and it keeps the first, which is what you&#x27;d
expect and not what a naive implementation does.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The modelling decision that made this clean: a selection isn&#x27;t a second thing to
track alongside the caret, it&#x27;s &lt;strong&gt;the range between a caret and an anchor&lt;&#x2F;strong&gt;. So
focus became &lt;code&gt;{ model, caret, anchor }&lt;&#x2F;code&gt;, and the one restore pass that puts the
caret back after a rebuild puts the selection back too. Given that v0.1&#x27;s nastiest
bug was a restore pass that only handled half its job, not adding a second one
mattered.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The trap worth writing down:&lt;&#x2F;strong&gt; parley will hand you selection rectangles, and
they&#x27;re laid out on &lt;em&gt;parley&#x27;s&lt;&#x2F;em&gt; line pitch. Rux draws lines with the leading
trimmed, which is a different pitch. Take those rects as-is and the highlight
drifts a little further off the glyphs with every wrapped line. It&#x27;s invisible in a
one-line field, obvious the moment you drag through a textarea. So Rux takes only
the &lt;em&gt;horizontal&lt;&#x2F;em&gt; extent from parley and recomputes the vertical from its own line
stepping, keyed by the line index parley helpfully returns beside each rect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;select-textarea-and-keyboard-focus&quot;&gt;select, textarea, and keyboard focus&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;type=&quot;textarea&quot;&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; — multi-line: Enter inserts a newline, the value wraps,
Up&#x2F;Down move the caret between lines, and it scrolls vertically with the caret
kept in view as you type.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;type=&quot;select&quot;&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; — shows the bound value and opens a dropdown of &lt;code&gt;:options&lt;&#x2F;code&gt;:
one floating panel with a shadow, the current value as a pill, hairline
separators.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Tab &#x2F; Shift+Tab&lt;&#x2F;strong&gt; now move a focus ring through every focusable: text inputs,
buttons, checkboxes, radios, selects. &lt;strong&gt;Space&#x2F;Enter&lt;&#x2F;strong&gt; activates the focused
one. Tabbing to something below the fold scrolls it into view.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Two fixes came straight out of using it: inputs were &lt;strong&gt;hugging their text and
shrinking as you typed&lt;&#x2F;strong&gt; (they now default to &lt;code&gt;width: 100%&lt;&#x2F;code&gt;), and single-line
inputs wrapped when they should clip.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scrolling-that-behaves-like-scrolling&quot;&gt;Scrolling that behaves like scrolling&lt;&#x2F;h2&gt;
&lt;p&gt;v0.1&#x27;s scrolling was wheel-only and vertical-only. Now:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Horizontal scrolling&lt;&#x2F;strong&gt; — the offset is two-axis, so a box scrolls whichever
way its content actually overflows. Shift+wheel goes sideways.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scrollbars&lt;&#x2F;strong&gt; — an overlay on the box&#x27;s trailing edge, only on an axis that has
travel, with the thumb sized as the box&#x27;s fraction of the content (floored so
it stays grabbable). When both axes scroll, the tracks stop short of the corner.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Drag&lt;&#x2F;strong&gt; a thumb, and a press on a thumb never becomes a tap on the content
underneath it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Keyboard&lt;&#x2F;strong&gt; — arrows, PageUp&#x2F;PageDown, Home&#x2F;End scroll the box under the
pointer, reached only after a focused input has declined the key.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Touch&lt;&#x2F;strong&gt; — a finger drags the content. This is the one piece here that has
&lt;strong&gt;not&lt;&#x2F;strong&gt; been verified on real hardware; there&#x27;s no touch device on the machine
it was written on.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The bug in this batch is a good advertisement for looking at things. The
horizontal thumb was painted using the track&#x27;s &lt;em&gt;length&lt;&#x2F;em&gt; as its thickness: a pale
slab across the entire box, impossible to miss on screen, and completely invisible
to a test suite that only ever checked the vertical bar. The axis you didn&#x27;t test
is the axis that&#x27;s broken.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-css-push&quot;&gt;The CSS push&lt;&#x2F;h2&gt;
&lt;p&gt;The biggest gap in v0.1 wasn&#x27;t a missing feature, it was &lt;strong&gt;silence&lt;&#x2F;strong&gt;: you wrote
valid CSS, nothing happened, and nothing told you why. v0.2 attacks that from both
ends: more honored properties, and a warning when a declaration is ignored.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Newly honored:&lt;&#x2F;strong&gt; &lt;code&gt;font-family&lt;&#x2F;code&gt; (you could not choose a font at all before, the
single most visible gap), &lt;code&gt;font-style&lt;&#x2F;code&gt;, &lt;code&gt;letter-spacing&lt;&#x2F;code&gt;, &lt;code&gt;word-spacing&lt;&#x2F;code&gt;,
&lt;code&gt;line-height&lt;&#x2F;code&gt;, &lt;code&gt;text-decoration&lt;&#x2F;code&gt;, &lt;code&gt;white-space: nowrap&lt;&#x2F;code&gt;, &lt;code&gt;box-shadow&lt;&#x2F;code&gt;, linear and
radial &lt;code&gt;gradients&lt;&#x2F;code&gt;, &lt;code&gt;background-image: url()&lt;&#x2F;code&gt;, &lt;code&gt;transform&lt;&#x2F;code&gt; (translate&#x2F;scale&#x2F;rotate),
per-corner &lt;code&gt;border-radius&lt;&#x2F;code&gt;, &lt;code&gt;grid-column&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;grid-row&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;grid-auto-*&lt;&#x2F;code&gt;,
&lt;code&gt;aspect-ratio&lt;&#x2F;code&gt;, &lt;code&gt;position&lt;&#x2F;code&gt; + inset, &lt;code&gt;align-self&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;justify-self&lt;&#x2F;code&gt; &#x2F;
&lt;code&gt;align-content&lt;&#x2F;code&gt;, &lt;code&gt;row-gap&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;column-gap&lt;&#x2F;code&gt;, and &lt;code&gt;cursor: pointer&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;And two silent-wrongness bugs, which are worse than gaps:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;+&lt;&#x2F;code&gt; and &lt;code&gt;~&lt;&#x2F;code&gt; were all matched as descendant combinators.&lt;&#x2F;strong&gt; &lt;code&gt;.a &amp;gt; .b&lt;&#x2F;code&gt; was
quietly styling grandchildren. Selectors now record a combinator per compound
pair and match accordingly, siblings included.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Named colours didn&#x27;t resolve.&lt;&#x2F;strong&gt; Worse, lightningcss &lt;em&gt;minifies&lt;&#x2F;em&gt; &lt;code&gt;#ff0000&lt;&#x2F;code&gt; into
&lt;code&gt;red&lt;&#x2F;code&gt;, so writing plain hex red got you the default colour. A full CSS
named-colour table now backs the parser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;transform&lt;&#x2F;code&gt; came with a caveat that&#x27;s documented rather than hidden: hit, focus
and scroll regions are computed untransformed, so a transformed element still taps
at its original position.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;still-missing&quot;&gt;Still missing&lt;&#x2F;h2&gt;
&lt;p&gt;Written as plainly as the wins:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CSS&lt;&#x2F;strong&gt;: variables and &lt;code&gt;var()&lt;&#x2F;code&gt;, &lt;code&gt;@media&lt;&#x2F;code&gt;, pseudo-classes (&lt;code&gt;:hover&lt;&#x2F;code&gt;, &lt;code&gt;:focus&lt;&#x2F;code&gt;,
&lt;code&gt;:checked&lt;&#x2F;code&gt;; the synthetic &lt;code&gt;checked&lt;&#x2F;code&gt; class is a stopgap waiting for them),
&lt;code&gt;!important&lt;&#x2F;code&gt;, per-side border &lt;em&gt;colours&lt;&#x2F;em&gt;, &lt;code&gt;box-sizing&lt;&#x2F;code&gt;, &lt;code&gt;text-overflow&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Text&lt;&#x2F;strong&gt;: no word-wise movement (Ctrl+arrows), no triple-click line select, no
drag-and-drop of a selection, no &lt;code&gt;::selection&lt;&#x2F;code&gt; styling.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scrolling&lt;&#x2F;strong&gt;: no track-click paging, no kinetic touch fling, and &lt;code&gt;overflow-x&lt;&#x2F;code&gt;
can&#x27;t differ from &lt;code&gt;overflow-y&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The big one&lt;&#x2F;strong&gt;: a signal change still rebuilds the whole tree.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;next-fine-grained-reactivity&quot;&gt;Next: fine-grained reactivity&lt;&#x2F;h2&gt;
&lt;p&gt;v0.2 shipped four features that each needed their own &lt;em&gt;restore pass&lt;&#x2F;em&gt;: put the
caret back, put the selection back, put the scroll offsets back, remember which
dropdown was open, remember where focus was. That list is now six entries long,
and every entry is a chance to reproduce v0.1&#x27;s caret bug.&lt;&#x2F;p&gt;
&lt;p&gt;Per-binding subscriptions delete the entire category. That&#x27;s v0.3, and it&#x27;s the
last real divergence between the architecture doc and the code.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rux v0.1.0 — it runs</title>
        <published>2026-07-15T00:00:00+00:00</published>
        <updated>2026-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://aine-dickson.github.io/rux/blog/v0-1-0/"/>
        <id>https://aine-dickson.github.io/rux/blog/v0-1-0/</id>
        
        <content type="html" xml:base="https://aine-dickson.github.io/rux/blog/v0-1-0/">&lt;p&gt;Rux v0.1.0 is tagged. It opens a native window, lays a &lt;code&gt;.rux&lt;&#x2F;code&gt; file out with real
flexbox and CSS grid, shapes text, edits inputs with a blinking caret, scrolls
lists, draws images, and reloads live when you save. No browser, no webview, no
JavaScript.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the announcement. The more useful part of this post is what building it
taught, so let&#x27;s do both.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-v0-1-is&quot;&gt;What v0.1 is&lt;&#x2F;h2&gt;
&lt;p&gt;Nine milestones&#x27; worth of runtime, in ten crates and about 6,000 lines:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Layout&lt;&#x2F;strong&gt; — flexbox &lt;em&gt;and&lt;&#x2F;em&gt; CSS grid via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DioxusLabs&#x2F;taffy&quot;&gt;taffy&lt;&#x2F;a&gt;, the full box model
(per-side padding&#x2F;margin&#x2F;border, shorthands, longhand overrides), sizing in
&lt;code&gt;px&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;%&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;rem&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;vw&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;vh&lt;&#x2F;code&gt;, and &lt;code&gt;minmax(0, 1fr)&lt;&#x2F;code&gt; grid tracks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Text&lt;&#x2F;strong&gt; — &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;linebender&#x2F;parley&quot;&gt;parley&lt;&#x2F;a&gt; shaping with system fonts, &lt;code&gt;font-weight&lt;&#x2F;code&gt;, &lt;code&gt;text-align&lt;&#x2F;code&gt;,
&lt;code&gt;overflow-wrap&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;word-break&lt;&#x2F;code&gt;, and leading trimmed so text hugs its box.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Inputs&lt;&#x2F;strong&gt; — &lt;code&gt;&amp;lt;input r-model=&quot;sig&quot;&amp;gt;&lt;&#x2F;code&gt; is a real text field: tap to focus,
click-to-position, arrows, Home&#x2F;End, Backspace&#x2F;Delete, and a caret that blinks
at 530 ms and survives the rebuild after every keystroke. Plus checkbox and
radio as tap-toggles.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scrolling&lt;&#x2F;strong&gt; — &lt;code&gt;overflow: auto&lt;&#x2F;code&gt; scrolls with the wheel, and offsets survive a
rebuild, so tapping a row doesn&#x27;t jump the list to the top.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Images, opacity, clipping&lt;&#x2F;strong&gt;, HiDPI, and a recursive file watcher so imported
components hot-reload too.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Signals&lt;&#x2F;strong&gt; driving &lt;code&gt;{{ }}&lt;&#x2F;code&gt; bindings, &lt;code&gt;r-for&lt;&#x2F;code&gt;, &lt;code&gt;r-if&lt;&#x2F;code&gt;, &lt;code&gt;r-model&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;56 tests pass. Every example has been driven on screen — which brings us to the
thing worth writing down.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-lesson-tests-didn-t-catch-anything-that-mattered&quot;&gt;The lesson: tests didn&#x27;t catch anything that mattered&lt;&#x2F;h2&gt;
&lt;p&gt;For most of the build, Rux was verified by &lt;code&gt;cargo test&lt;&#x2F;code&gt;. The suite was green and
growing, and it inspired a confidence that turned out to be completely
unearned. The first time the examples were actually run and &lt;em&gt;looked at&lt;&#x2F;em&gt;, bugs
fell out within seconds — and &lt;strong&gt;every single one had been invisible to the tests&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Text re-wrapped over its own siblings.&lt;&#x2F;strong&gt; &lt;code&gt;measure&lt;&#x2F;code&gt; returned a fractional
natural width (98.001px), taffy rounded the box down to 98px, and paint
re-wrapped the text at the box width it was given — breaking the last word onto
a line the box had no height for. It looked random because it depended on which
way each string&#x27;s width happened to round. The fix is one &lt;code&gt;ceil()&lt;&#x2F;code&gt; and
&lt;code&gt;disable_rounding()&lt;&#x2F;code&gt;; the invariant is &lt;em&gt;a text box must never be narrower than
the text measured&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Boxes burst out of their parents.&lt;&#x2F;strong&gt; A box with no width took its full
max-content size, so a row of three 320px cards inside a 320px card laid out at
976px and hung off the side. &quot;Hug&quot; had to mean CSS &lt;code&gt;fit-content&lt;&#x2F;code&gt;, not
max-content.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A wrapping grid mis-measured its own height&lt;&#x2F;strong&gt;, reserving one row while
painting two, so the thing below rode up over it. That one is a taffy bug that
is still present in 0.12; Rux works around it in the &lt;code&gt;to_taffy&lt;&#x2F;code&gt; mapping.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;@tap&lt;&#x2F;code&gt; inside &lt;code&gt;r-for&lt;&#x2F;code&gt; silently did nothing.&lt;&#x2F;strong&gt; &lt;code&gt;@tap=&quot;picked = item&quot;&lt;&#x2F;code&gt; couldn&#x27;t
see the loop variable, because handlers run later in global scope where &lt;code&gt;item&lt;&#x2F;code&gt;
no longer exists. Loop bindings are now baked into the handler as a &lt;code&gt;let&lt;&#x2F;code&gt;
prelude at build time. Nothing in the suite ever tested a handler that used a
loop variable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The caret stayed in the input you&#x27;d just left.&lt;&#x2F;strong&gt; The restore pass that puts
the caret back after a rebuild only ever &lt;em&gt;set&lt;&#x2F;em&gt; a caret — it never cleared one.
The test asserted the caret appeared in the focused input; it never asserted it
&lt;em&gt;disappeared&lt;&#x2F;em&gt; from the other.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That last one is the pattern: the test checked the positive case and stopped.
Tests protect against regression. They do not tell you it works. &lt;strong&gt;A feature is
not done until it has been driven in the window&lt;&#x2F;strong&gt; — that&#x27;s now the rule, and it
has paid for itself in every release since.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-renderer-upgrade-that-looked-like-a-disaster&quot;&gt;The renderer upgrade that looked like a disaster&lt;&#x2F;h2&gt;
&lt;p&gt;v0.1 needed &lt;code&gt;OverflowWrap&lt;&#x2F;code&gt;, &lt;code&gt;WordBreak&lt;&#x2F;code&gt; and a real text &lt;code&gt;Cursor&lt;&#x2F;code&gt;, none of which
parley 0.2 had. So: vello 0.3 → 0.9, parley 0.2 → 0.11.&lt;&#x2F;p&gt;
&lt;p&gt;It exploded immediately with wgpu-hal errors that looked exactly like a
&lt;code&gt;windows&lt;&#x2F;code&gt;-crate version split — the kind of dependency knot that eats a day. It
wasn&#x27;t. It was a &lt;strong&gt;stale lockfile&lt;&#x2F;strong&gt;: an old &lt;code&gt;gpu-allocator&lt;&#x2F;code&gt; pinned in place.
&lt;code&gt;cargo update -p gpu-allocator&lt;&#x2F;code&gt; fixed the whole thing. The real API churn was
confined to three crates, and the one genuine trap was that vello 0.9 dropped
&lt;code&gt;render_to_surface&lt;&#x2F;code&gt; — you now render into the surface&#x27;s intermediate target and
blit, because rendering straight to a surface texture panics (Bgra8 vs Rgba8
storage).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-v0-1-is-not&quot;&gt;What v0.1 is not&lt;&#x2F;h2&gt;
&lt;p&gt;Being clear about this, because a first release invites the wrong expectations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No text selection and no clipboard.&lt;&#x2F;strong&gt; You can edit a field; you can&#x27;t select
in it, copy from it, or paste into it.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;No &lt;code&gt;select&lt;&#x2F;code&gt; or &lt;code&gt;textarea&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;, and checkboxes and radios can&#x27;t be reached by
keyboard.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scrolling is wheel-only and vertical-only.&lt;&#x2F;strong&gt; No scrollbars, no drag, no
keyboard, no horizontal.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CSS has real holes&lt;&#x2F;strong&gt; — no variables, no &lt;code&gt;@media&lt;&#x2F;code&gt;, no pseudo-classes, and no
way to pick a font at all. Worse, unknown properties are &lt;em&gt;silently ignored&lt;&#x2F;em&gt;,
which is the worst failure mode the project has.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A signal change rebuilds the whole tree.&lt;&#x2F;strong&gt; Fine at these sizes, but it&#x27;s why
every piece of ephemeral state needs restoring by hand.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Cross-DPI dragging is unverified&lt;&#x2F;strong&gt; — the machine here has one monitor.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And the honest framing question, which a group of developers put bluntly when they
saw it: &lt;em&gt;this isn&#x27;t novel.&lt;&#x2F;em&gt; Flutter, Slint and Lynx all render GPU UI without a
browser. That&#x27;s true, and worth repeating on the front page rather than hiding:
Rux&#x27;s only real claim is the ergonomic one — literal CSS, pure Rust, no DSL, no
JS. Whether that combination is genuinely nicer is the thing v0.1 exists to find
out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;&#x2F;h2&gt;
&lt;p&gt;v0.2: text selection and clipboard, the last two input types, scrolling polish,
and a serious CSS push — starting with &lt;code&gt;font-family&lt;&#x2F;code&gt;, because &quot;you cannot choose a
font&quot; is the most visible gap on the list.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
