0.0.23 cohort: faster frames, pictures and video in Noctiluca, and the marketplace goes live¶
Published on 2026-10-27, every crate by one release run, with
rs-rich
0.0.11 on PyPI. See Publication.
0.0.23 began as what 0.0.22 handed on and grew as the
maintainer brought items forward from later releases. The core finishes
porting console.py, the last partial library row, and gets faster while
its bytes stay the same. intuiTUIve paints with fewer bytes and gains what
rs-rich-doom built for itself. Noctiluca draws a page's pictures, GIFs and
video, and was tried on eight real sites. The plugin marketplace is live and
signed, with its own website. The 0.0.23 plan has
every item; what moves on is in 0.0.24.
console.pyfully ported.quiet, upstream's size rules and setters, colour and terminal detection from the environment (COLORTERM,TERM,TTY_COMPATIBLE,FORCE_COLOR),on_broken_pipe, capture,record=with the text, HTML and SVG exports,log, render hooks,set_live/clear_live,screen()andstatus().Progress.logworks, and a nestedLivedraws inside the first display, as in rich 15.0.0. New golden fixtureconsole.tsv. Every library row in PORTING is now complete or a recorded divergence.- Themes reach Markdown. A theme's
markdown.*styles show inrich -m, and--theme-style repr.number=…is no longer overridden by a fixed colour. - rich renders faster, byte for byte the same. Fast paths beside the
ported code (colour names, character widths, markup tags, style
normalisation, word wrapping), each pinned by a test, and
Segment.textandColor.nameasCompactStrings. A table of markup redraws in a third of the time, and drawing a colour swatch as segments allocates 111 times a frame, down from 5,871. The goldens, the parity tables, the differential fuzzer and a byte compare of 30,081 cases against the previous binary all agree. - rs-rich-ext's fast path.
surface::Drawwrites cells straight into aScreen; the charts, gauges, heatmaps and the other viz renderables implement it, and intuiTUIve draws with it by default. Every cell changing at 80x24 takes 104 µs, against ratatui's 340. - Paint strategies, with
bestthe default.bestscrolls rows that moved together with the terminal's own scrolling and otherwise paints cells: a log scrolled one row sends 147 bytes a frame, down from 4,013.App::paint_strategyandRICH_PAINT_STRATEGYchoose another, andApp::timedemoreplays a script on the driver's clock and reports every frame. A benchmark gate keepsbestwithin 5% of the best fixed strategy. - Long pages and endless feeds.
scroll_virtualbuilds only the items near the view, with no row cap, and loads more near the end. - rs-rich-doom's core gaps. Raw Kitty frames, Sixel in a palette of one's own, pixel cells in their own colours, a picture fitted in a pixel buffer, a worker in lockstep with the app's clock, sound without a sound card, a voice mixer and an output that calls a renderer. See the gaps.
- Sound in recordings.
Set Audio onin a tape, orrich record --audio, records what an intuiTUIve app plays: an MP4 gets an AAC track, and the other formats a WAV beside them. Off by default. - Pictures and video in Noctiluca. Pictures are drawn where the page
puts them, in Kitty, iTerm2, Sixel or half blocks; animated GIFs move; a
playing video plays in its region, within the terminal's byte budget.
Media controls, a header and status bar after the proof of concept, and
about:noctiluca. See Media. - Noctiluca follows live logs (
role=log,aria-live) and has eleven named terminal adaptations, each one switchable (Adaptations). Long pages and feeds scroll with no row cap. - Noctiluca on real sites. A gallery of BBC News, Wikipedia, Hacker News, MDN, The Guardian, GitHub, YouTube and Twitch. Recording it fixed seven layout bugs. Its own video fixtures replace the old garbled clip, and the guide plays Noctiluca's promo.
- WebP everywhere.
rich image,rich view,rich gif,--diff, rs-rich-art, micro assets and Noctiluca read WebP, and an animated WebP plays like a GIF. Sixel keeps a picture's exact colours when it has 256 or fewer. - The plugin marketplace is live. Its index is signed, and the official
keys are compiled in, so
rich plugintrusts it with no flags. It lists the Mermaid, DOT and lumis crates, two official WASM plugins (textcaseandwordplay), five themes and three micro packs. It shows downloads, ratings and reviews, andrich plugin searchfilters by kind, tier and recommendation. Installed themes work with--theme, and installed micro packs load on every run. The marketplace has its own site, and the docs have a Marketplace page. - HTTPS trusts the system's certificates. Plugin installs,
rich <url>and the download statistics work behind a TLS-inspecting proxy, follow redirects one at a time and keep one timeout for the whole chain. rich --rstfollowsrich-rst2.2.0: a docutils document tree with its transforms, real tables, numbered footnotes and the newer directives.- API checks and fuzzing, brought forward from later stages. Every
crate's public API is snapshotted and checked in CI with
cargo-semver-checks. Fuzz targets for every parser that takes outside input run nightly (fuzzing); the three bugs they found are fixed. The Python package's type stubs passstubtestandmypy --strict. - The docs load nothing from other sites: fonts are served with the site, and the header no longer asks GitHub's API for stars.
- intuiTUIve against Textual. A parity audit maps Textual's widgets to intuiTUIve's and files the gaps as issues #797 to #815, for the releases before 1.0.0.
A default build of rs-rich still renders exactly like upstream rich
15.0.0.
Independent package versions¶
| Package | Version | Release role |
|---|---|---|
rs-rich |
0.0.13 | console.py ported; Progress.log; nested Live; themes in Markdown; fast paths; CompactString strings; FORCE_COLOR, TTY_COMPATIBLE and exit status 1 on a broken pipe; AnsiDecoder fix |
rs-rich-macros |
0.0.7 | Manifest only; requires core 0.0.13 |
rs-rich-plugin-api |
0.0.7 | Requires core 0.0.13; the textcase example |
rs-rich-art |
0.0.16 | WebP; raw Kitty frames; exact-palette Sixel; the picture and frames features (Picture, Player, ByteBudget, Pacer) |
rs-rich-diagram |
0.0.6 | Manifest only |
rs-rich-mermaid |
0.0.9 | Manifest only |
rs-rich-lumis |
0.0.7 | Manifest only |
rs-rich-ext |
0.0.20 | rst as a document tree (rich-rst 2.2.0); surface::Draw fast path; Surface on best; the faster painter and PaintStats; WASM sandbox fixes; zip 9; rich's widths for U+9FBC to U+9FFF |
rs-rich-micro |
0.0.9 | WebP, animated; zip 9 |
rs-rich-record |
0.0.11 | Sound in tapes; raw Kitty frames in the emulator; no frame kept mid synchronized update |
rs-rich-interact |
0.0.11 | A woken session reads a waiting key at once; keymaps look up without allocating; signal-hook 0.4 |
rs-rich-ratatui |
0.0.8 | Follows core's CompactString |
rs-rich-intuituive |
0.0.8 | Paint strategies (best the default), timedemo, richer FrameStats; scroll_virtual, damage_since; drawn nodes; rs-rich-doom's gaps (pixel_colors, draw_fitted, stepped_worker, null outputs, taps, Mixer, output_with); sound in tapes; picture_of; a hidden switch page fix |
rs-rich-embed |
0.0.6 | Screencast on demand, cropped frames, screencast off |
rs-rich-web |
0.0.6 | Frame compression (Server::compress); damage-only DOM diffs; the memory limit fix |
rs-rich-data |
0.0.7 | Manifest only |
rs-rich-marketplace |
0.0.2 | Official keys compiled in (KeySet::official); system TLS trust (tls); redirects with one deadline (redirect); the recommended listing key |
noctiluca |
0.0.2 | Pictures, GIFs and video; live logs; terminal adaptations; long pages; WebP; seven fixes from real sites |
rs-rich-cli |
0.0.23 | rich --rst on rich-rst 2.2.0; the marketplace's search filters, statistics, official packages, installed themes and micro packs; record --audio; serve --compress; system TLS trust; WebP; the console contract kept |
The Python package, rs-rich 0.0.11 on PyPI, builds against these crates.
Its type stubs are complete, and its console size follows upstream's rules.
Migration¶
Breaking changes in 0.0.x crates (the
CHANGELOG
has each, and api/semver-breaks.toml lists them with their reasons):
- rs-rich:
Segment.textandColor.nameareCompactStrings. Reads compile unchanged. Where aStringwas moved out, write.to_string()or.into_string(); where one is assigned, add.into().Segment::newtakesimpl Into<CompactString>. - rs-rich: the console reads
FORCE_COLORandTTY_COMPATIBLE, as rich 15.0.0 does. For the oldisatty-only rule, build with.force_terminal(std::io::stdout().is_terminal()). - rs-rich: a broken pipe ends the process with status 1. To carry on,
give
ConsoleBuilder::on_broken_pipea handler, such as.on_broken_pipe(|console| console.set_quiet(true)). Therichbinary keeps exiting 0. - rs-rich-ext:
rst::parsereturns the document tree (rst::Element);Block,Inlineand friends are gone. Rendering withRestructuredText::newis unchanged. - rs-rich-ext: a painter's
Cellis 12 bytes andCopy; read its text withCell::text(), since thetextfield is gone. - rs-rich-intuituive:
FrameStatsgains fields, andImageViewandPixelscome from rs-rich-art. Apps paint withbestby default; choosePaintStrategy::Cellsfor 0.0.22's behaviour. - rs-rich-record:
Recordinghas a newaudiofield andOptionsa newaudioswitch. - rs-rich-ext and rs-rich-micro use zip 9: rs-rich-ext lists an entry whose name cannot be decoded lossily, and rs-rich-micro refuses it.
- The CLI:
rich plugin search's no-match message names the marketplace's site first, and numbers follow--theme-style repr.numberalone.
Release test¶
- The release gate (
scripts/validate_release.py --tag release-0.0.23) onmainatb4bcaeewith the Textual audit and the notes on top (docs only), in a Linux container on Rust 1.99: fmt; clippy-D warningswith default features,--all-features, and the CLI without default features;cargo test --all(6,124 passed, 17 ignored, none failed), the CLI without default features (593 passed) and the plugin loaders (32 passed); the five release script suites (161 tests); the version tables,RELEASES.tomland the CLI reference up to date;cargo check --workspace --locked;check_packages.py(every crate packaged and verified);release.py plan release-0.0.23 --semver-checksselecting all 19. The tests were built without debug info, to fit the container's disk. - The golden fixtures (39 files, 4,806 cases) regenerate byte for byte
from rich 15.0.0, in a virtualenv with only
rich15.0.0. - The docs tapes: all 75 tapes, 291 screenshots, match with a release build of the CLI and the examples, built with CI's features.
- The docs:
mkdocs build --strictfor both sites. - The declared MSRV: CI's checks on Rust 1.90 (the workspace with every feature, and the CLI with CI's features) and on 1.91 (rs-rich-lumis, and the CLI with every feature).
- CI on #823's head (
d1341be, whose tree ismainatb4bcaee): every check passed, including the feature matrix, the live browser job, the macOS and Windows jobs, the API and SemVer job, the benchmark gates and the WASM release tests this pass did not run.
Not in this release¶
- AVIF is not decoded by rs-rich-art; Noctiluca takes AVIF pictures from
Chrome's pixels. An opt-in
aviffeature is planned for 0.0.24. - lumis 0.17 waits: it raises rs-rich-lumis's minimum Rust to 1.95.
- One fuzzer case remains a known divergence: #769.
- The signer still pushes with a deploy key; the move to a GitHub App is part of 1.0.0.
Known limits¶
See Known issues, which applies to this release. Still open: the recorder keeps fewer frames on macOS and Chrome's DevTools port on Windows.
Publication¶
- On 2026-10-27, on
mainat2624ce5(#824), the 19 record tags (rs-rich-v0.0.13,rs-rich-macros-v0.0.7,rs-rich-plugin-api-v0.0.7,rs-rich-art-v0.0.16,rs-rich-diagram-v0.0.6,rs-rich-mermaid-v0.0.9,rs-rich-lumis-v0.0.7,rs-rich-ext-v0.0.20,rs-rich-micro-v0.0.9,rs-rich-record-v0.0.11,rs-rich-interact-v0.0.11,rs-rich-ratatui-v0.0.8,rs-rich-intuituive-v0.0.8,rs-rich-embed-v0.0.6,rs-rich-web-v0.0.6,rs-rich-data-v0.0.7,rs-rich-marketplace-v0.0.2,noctiluca-v0.0.2,rs-rich-cli-v0.0.23), thenrelease-0.0.23andpython-v0.0.11, each withRelease: 0.0.23andCommit:lines (17:50 UTC). - The one
release.ymlrun forrelease-0.0.23ran the full gate (61 jobs, all passed), then published every crate inRELEASES.toml's order and verified each version from crates.io (the uploads from 18:42 to 18:44 UTC, verified by 18:52; run). Every crate went up through Trusted Publishing,rs-rich-marketplaceandnoctilucafor the first time. - The Python package,
python-v0.0.11on2624ce5, throughpypi-release.yml: built with the crates, tested, then published to PyPI at 19:12 UTC (run). Its first attempt's macOS arm64 wheel never got a runner and was cancelled; the re-run of that job built it, and the rest of the run went on from there. - The docs workflow ran on the tag push.
Follow-up¶
- The marketplace lists the new versions of the official crates
(
mermaid0.0.9,dot0.0.6,lumis0.0.7), and itsRS_RICH_CLI_REFmoves torelease-0.0.23, through a pull request to rs-rich-marketplace.