experimental: ratatui → frankentui migration (Phase 1+2, 1/8 crates done)#312
Open
quangdang46 wants to merge 6 commits into
Open
experimental: ratatui → frankentui migration (Phase 1+2, 1/8 crates done)#312quangdang46 wants to merge 6 commits into
quangdang46 wants to merge 6 commits into
Conversation
Investigation results on experimental branch. Verdict: NOT recommended as 1:1 migration. Frankentui's authors explicitly state 'no backwards compatibility, no upgrade path' and the type shapes differ enough that every Widget impl, Color usage, and Buffer interaction needs rewrite. Findings: - jcode has 275 ratatui::* references across 66 files / 9 crates - Color enum nesting differs: Color::Red → Color::Ansi16(Ansi16::Red) - Widget::render signature: takes &Frame instead of &mut Buffer - Buffer cell layout: 16-byte aligned, grapheme pool ID, no string symbols - Test backend pattern is incompatible: 51 sites use ratatui::TestBackend - ratatui-image (used by mermaid renderer) has no frankentui equivalent Surprise: ftui-style compiles on stable Rust despite nightly toolchain file, though deeper subcrates may still need nightly. Realistic migration estimate: 2-4 weeks dev + 1-2 weeks UI regression hunt. ROI unclear without measured perf bottleneck pointing at ratatui. Recommendation: skip migration. ratatui is mature + stable; frankentui is WIP 0.4.0 + 850K LOC dependency surface increase. Higher-ROI alternatives exist (port more upstream PRs, ship deferred features). If forced to prototype, start with jcode-tui-usage-overlay (1 ratatui ref, 134 lines) behind a feature flag — 1-2 days throwaway.
Phase 1 of the ratatui → frankentui experimental migration. The smallest ratatui consumer in the workspace (jcode-tui-usage-overlay, 134 LOC, 1 ratatui ref) now exposes a parallel frankentui-shaped color API behind the new `frankentui` cargo feature, without removing the existing ratatui-shaped API that downstream callers already rely on. Design: - Introduce `pub const fn rgb(self) -> (u8, u8, u8)` as the single source of truth for status colors. - `color() -> ratatui::style::Color` (existing API, untouched return type) delegates to `rgb()`. - New `color_ftui() -> ftui_style::Color`, gated by `#[cfg(feature = "frankentui")]`, delegates to the same `rgb()`. - Locked the contract with two new tests (one feature-gated) that round- trip through both backends and assert RGB equivalence via `ftui_style::Color::to_rgb()`. Dependency: - `ftui-style` is pulled as an optional git dep pinned to quangdang46/frankentui@33ad1c57 — no path dep so other machines do not need a sibling /data/projects/frankentui checkout. Frankentui's ftui-style crate compiles cleanly on jcode's existing nightly toolchain (rustc 1.98.0-nightly). Cargo.lock: - unicode-width 0.2.0 → 0.2.2 (required by ftui-core; jcode's `= "0.2"` requirement already permits this). - bitflags 2.10.0 → 2.11.1 (required by ftui-render; crossterm's `= "2.9"` permits it). - bumpalo 3.19.1 → 3.20.3 (required by ftui-render; wasm-bindgen-macro- support's `= "3.0"` permits it). No Cargo.toml version requirements were widened. Verified: - `cargo check -p jcode-tui-usage-overlay` (default features): clean. - `cargo check -p jcode-tui-usage-overlay --features frankentui`: clean. - `cargo test -p jcode-tui-usage-overlay`: 4/4 pass (default), 5/5 pass (--features frankentui). - `cargo check -p jcode --lib`: clean (consumer src/tui/usage_overlay.rs unchanged, still uses ratatui Color via color()). See docs/RATATUI_MIGRATION_FEASIBILITY.md for the full Phase 1 writeup, the list of questions this prototype did and did not answer, and the recommended next slice (jcode-tui-style).
Phase 2 of ratatui → frankentui migration. The crate is now fully ratatui-free — its Cargo.toml has no ratatui dep. Public API: UsageOverlayStatus::color() -> ftui_style::Color Phase 1's dual-color API (color() ratatui + color_ftui() frankentui behind a feature flag) is collapsed. Consumer adaptation (src/tui/usage_overlay.rs still drives ratatui rendering): - New module src/tui/ftui_compat.rs with ftui_color_to_rata() that matches every ftui_style::Color variant onto the closest ratatui Color variant (Rgb 1:1, Ansi256 numeric, Ansi16 named, Mono → black/ white). 5 unit tests cover the variant mapping. - Local helper status_color_rata(status) wraps the conversion at the three Style::fg() call sites in usage_overlay.rs. Top-level Cargo.toml gains an ftui-style git dep pinned to the same quangdang46/frankentui@33ad1c57 commit Phase 1 used. ftui-compat is intentionally an explicit, easy-to-grep boundary — it disappears once the rendering layer itself stops using ratatui. Verified: - cargo test -p jcode-tui-usage-overlay: 4/4 pass. - cargo check -p jcode --lib: clean (existing 7 dead-code warnings unrelated to this change). Crate count update: 1 of 8 crates is now ratatui-free.
Documents what landed in commit 67fc2c3 (jcode-tui-usage-overlay full migration), what was attempted and reverted (jcode-tui-style had 687 type errors across 502 call sites in 50 consumer files), and why each remaining crate is blocked. Key findings: - ratatui 0.30's Style::fg signature is `pub const fn fg(self, color: Color) -> Self` — takes Color exactly, not impl Into<Color>. So every leaf crate that returns ftui_style::Color triggers explicit conversion at every Style::fg/bg call site. - The orphan rule prevents adding From<ftui_style::Color> for ratatui::style::Color from a third crate. - jcode-tui-markdown has no migration target — frankentui's own migration-map.md explicitly defers markdown rendering to Phase 5 (`ftui-extras`), not yet implemented. - jcode-tui-mermaid has no migration target — frankentui has no ratatui-image equivalent (also Phase 5). Final status: 1 of 8 crates migrated (usage-overlay), 5 deferred to structural-rewrite work that must happen in dedicated PRs (style, workspace, render, messages, top-level jcode), 2 hard-blocked on upstream frankentui Phase 5 work (markdown, mermaid). Phase 1 and Phase 2 each took ~1 hour and represent the easy work; the original 2–4 week estimate at the top of this doc still stands for the remaining 5 deferred crates.
…_support Phase 3 + Phase 4 of ratatui → frankentui migration. Phase 3: jcode-tui-style is fully ratatui-free. - Cargo.toml: drop ratatui = "0.30", add ftui-style git dep. - color.rs/theme.rs: every public API returns ftui_style::Color. - clear_buf removed (it operated on ratatui Buffer; not the leaf crate's responsibility). All 502 caller sites in 50 files keep working unchanged because src/tui/color_support.rs and src/tui/ui_theme.rs wrap the leaf-crate output back to ratatui::Color via new .rata() / .ftui() extension traits in src/tui/ftui_compat.rs. ftui_compat gains: - FtuiColorExt trait (.rata() on ftui_style::Color) - RataColorExt trait (.ftui() on ratatui::Color) - Total rata_color_to_ftui() covering every variant including Reset → Mono(White) - 8 round-trip tests Phase 4: jcode-tui-workspace::color_support deduplicated. - ~220 LOC of duplicate cube/gray/distance helpers deleted. - Now a thin wrapper that delegates to jcode_tui_style::color::rgb and converts to ratatui::Color at the boundary. - workspace's Cargo.toml gains jcode-tui-style + ftui-style deps but keeps ratatui because clear_buf and workspace_map_widget still operate on ratatui Buffer. Crate count: 2 of 8 ratatui-free (jcode-tui-usage-overlay + jcode- tui-style). The remaining 6 crates are blocked by either: - Architectural rewrite needed (Widget signature, Buffer cell layout, Terminal lifecycle, TestBackend pattern) — 5–10+ days each, must be done with shell verification per step. - Upstream frankentui Phase 5 features not yet shipped (markdown rendering, ratatui-image equivalent). See docs/RATATUI_MIGRATION_FEASIBILITY.md Phase 3 and Phase 4 sections for full writeup including the wrapper-funnel pattern and why it stops being usable at the rendering-layer boundary. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
d342dba to
0735654
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Experimental, multi-phase migration from
ratatuitofrankentui(ftui-style/ftui-render/etc.). Pinned againstquangdang46/frankentui@33ad1c57. This PR is incremental — it lands the work that can ship green now, and documents exactly what each remaining crate needs.Crate count: 1 of 8 ratatui-dependent crates is now ratatui-free.
What's in this PR
Phase 1 (commit
41f79c72)ftui-styleas an optional git dep injcode-tui-usage-overlay, gated by afrankentuicargo feature.UsageOverlayStatusto makepub const fn rgb() -> (u8,u8,u8)the single source of truth; both ratatui-shapedcolor()and the newcolor_ftui()delegate to it.unicode-width 0.2.0→0.2.2,bitflags 2.10.0→2.11.1,bumpalo 3.19.1→3.20.3.Phase 2 (commit
67fc2c35)jcode-tui-usage-overlayentirely. ItsCargo.tomlno longer mentions ratatui.ftui_style::Coloronly.src/tui/ftui_compat.rsexportsftui_color_to_rata(c: ftui_style::Color) -> ratatui::style::Color. It maps every variant offtui_style::Color(Rgb,Ansi256,Ansi16,Mono) onto the closest ratatuiColor. 5 unit tests cover the mapping.src/tui/usage_overlay.rs(the consumer) wraps the conversion via a privatestatus_color_rata()helper at the threeStyle::fgboundary sites.jcode/Cargo.tomlgains theftui-stylegit dep.Docs (commit
344493ad)docs/RATATUI_MIGRATION_FEASIBILITY.mdupdated with Phase 2 results and a precise crate-by-crate blocker analysis (see below).Verification
Remaining work — honest crate-by-crate status
jcode-tui-usage-overlayjcode-tui-styleStyle::fgtakesColordirectly (noInto) and the orphan rule blocksFromimpl from a third cratejcode-tui-workspacerender_workspace_map(buf: &mut ratatui::Buffer, …)is a ratatui-Buffer-based widget; can't migrate without rendering layer firstjcode-tui-renderBuffercell layout swap (16-byte aligned, grapheme-pool ID) is the structural hard stepjcode-tui-messagesBuffer/Span/Linejcode-tui-markdowndocs/migration-map.mddefers markdown rendering to Phase 5 /ftui-extras; not yet implementedjcode-tui-mermaidratatui-imageequivalent (also Phase 5 deferred)jcode(top-level)Terminal::new+ 51TestBackend::new+ widget consumers across 80+ filesWhy this PR doesn't finish the migration
Two distinct reasons:
Type-system rippling. ratatui 0.30's
Style::fgispub const fn fg(self, color: Color) -> Self(takesColorexactly, notimpl Into<Color>). The orphan rule blocks animpl From<ftui_style::Color> for ratatui::style::Colorfrom a third crate. So migrating any leaf crate that returnsColorripples into hundreds of explicit conversion calls at everyStyle::fg/bgsite.jcode-tui-stylealone has 502 such sites in 50 files.Hard upstream blockers. Frankentui's own
docs/migration-map.mdexplicitly lists markdown rendering and image protocols as Phase 5 / not implemented.jcode-tui-markdownandjcode-tui-mermaidtherefore have no migration target until frankentui ships those features (or jcode forks its own equivalents).Path forward (next PRs in this series)
src/tui/ftui_compat.rsso a bulk pattern_rewrite can mechanically transform 500+ call sites with safe local edits. Then migratejcode-tui-style.jcode-tui-render— swapratatui::Bufferforftui_render::Buffer/Frame. This is the first hard step where downstream signatures change.jcode-tui-workspace,jcode-tui-messages, plus the top-levelsrc/tui/*widget consumers).Terminallifecycle migration (Terminal::new/ratatui::init/restore→TerminalSession).TestBackend::new× 51 →ftui-harness).jcode-tui-markdown,jcode-tui-mermaid.The original 2–4 week estimate at the top of the feasibility doc still stands for the remaining 5 deferred crates.