# Feasibility Analysis: bDS Rewrite in Rust (Green-Field, No JavaScript) ## Context Green-field rewrite of bDS blogging CMS in pure Rust. No migration — only the on-disc content format (Markdown + YAML frontmatter) must be preserved. Everything else is up for debate. **Constraints:** - No JavaScript at all (supply chain security concern — no npm/webview/JS runtime) - Python scripting replaced with Rust-native scripting language (Lua) - WYSIWYG Markdown editor not needed — syntax-highlighting source editor is sufficient - Mac is first-class, Windows slightly behind, Linux as compatibility option - Built by team of AI agents, no timeline pressure - Green-field: existing codebase is reference only, not migrated --- ## Current Scale | Layer | LOC | Key Tech | |-------|-----|----------| | Main process (engines, IPC, DB) | ~45,800 | Node.js, 43+ engine classes, 257 IPC methods | | Renderer (UI) | ~30,200 | React 19, Zustand, 80 components, Milkdown, Monaco | | Tests | ~69,500 | Vitest, 210 test files | | Dependencies | 54 runtime + 27 dev | AI SDK, Pyodide, sharp, git, MCP, etc. | --- ## Rust GUI Framework Comparison (Mac-First) The "Mac must be first-class" constraint is critical. It reshuffles the ranking. ### Framework Assessment | Framework | Maturity | Mac Quality | Editor Story | Widget Set | |-----------|----------|-------------|-------------|------------| | **GTK4-rs + libadwaita** | 9/10 | 6/10 — functional but non-native feel (no system menu bar by default, non-native scrolling, GTK file dialogs) | GtkSourceView (excellent) | Rich | | **Iced** | 6/10 | 8/10 — GPU-rendered via Metal, consistent look, respects platform DPI. Not "native macOS" but consistent everywhere (like Electron was). | Custom needed (`syntect` + `ropey` + `cosmic-text`) | Growing, needs custom work | | **Floem** | 5/10 | 7/10 — used in Lapce which runs well on Mac | Lapce has one but not extracted | Sparse | | **Dioxus** | 4/10 | Variable | None | Tiny | | **Slint** | 7/10 | 7/10 — native rendering support | None | Limited | | **egui** | 8/10 | 7/10 — works well on Mac via wgpu | Wrong paradigm for editing | Immediate mode | ### Mac-specific concerns **GTK4 on macOS:** - Requires GTK4 installed (Homebrew/MacPorts) or bundled (~50MB overhead) - Doesn't use native macOS menu bar by default (can be configured but finicky) - Non-native scrolling physics, selection behavior, keyboard shortcuts - File/print dialogs look GTK, not macOS - Apps like GIMP/Inkscape run on Mac via GTK — functional but feel "foreign" **Iced on macOS:** - Renders via wgpu/Metal — native GPU acceleration - Consistent cross-platform look (no "foreign toolkit" feel) - You control all UX conventions (can implement macOS cmd-shortcuts, native-feeling scrolling) - No external toolkit dependency — statically compiled - Binary stays small (~10-20MB) - The trade-off: you build more widgets yourself, but AI agents can handle this ### The editor situation With WYSIWYG dropped, a syntax-highlighting text editor is achievable in pure Rust: | Approach | Effort | Quality | |----------|--------|---------| | **GtkSourceView** (GTK4 only) | 0 weeks (built-in) | Production-grade, 50+ languages | | **Custom iced widget** (`ropey` + `syntect` + `cosmic-text`) | 4-6 weeks | Good — proven building blocks, AI agents can build this | | **Extract cosmic-edit** from COSMIC | 3-4 weeks | Untested outside COSMIC | For an iced-based app, a custom editor widget built from `ropey` (rope buffer) + `syntect` (highlighting) + `cosmic-text` (text layout/shaping) is realistic. This is how Lapce and COSMIC's editors work internally. ### Recommendation: **Iced** Given Mac-first + no JS + green-field + AI agents building it: 1. **Iced** gives the best Mac experience without GTK's foreign feel 2. Custom editor is feasible (4-6 weeks for AI agents using proven crates) 3. GPU rendering (wgpu/Metal) = smooth, modern feel on all platforms 4. Elm architecture = predictable state management, good for AI-generated code 5. No external toolkit dependency = simpler distribution 6. System76 backing ensures continued development --- ## Scripting Language Replacement (Python → ?) | Language | Crate | Maturity | Speed | Ecosystem | Best For | |----------|-------|----------|-------|-----------|----------| | **Lua** | `mlua` | 10/10 | Very fast (LuaJIT) | Huge (30+ years, games, tools) | Battle-tested embedding, rich stdlib | | **Rhai** | `rhai` | 8/10 | Moderate | Small but growing | Rust-native, safe sandbox, no FFI | | **Starlark** | `starlark-rust` | 7/10 | Fast | Niche (Bazel/Buck) | Python-like syntax, deterministic | **Recommendation: Lua via `mlua`.** - Most mature embedding story. Used by Neovim, Redis, nginx, game engines. - `mlua` supports Lua 5.4 and LuaJIT. Sandboxing built in. - Exposing engine methods to Lua is trivial (`mlua::UserData` trait). - Distribution: Lua runtime is ~300KB, compiled into the binary. No external install needed. - Existing Python macros would need rewriting, but Lua syntax is simple for end users. --- ## Two Viable Paths ### Path A: Iced (Recommended — Mac-first, fully native, zero JS) | Aspect | Assessment | |--------|-----------| | **JS purity** | 100%. No webview, no JS runtime, no npm. | | **Rendering** | wgpu (Metal on Mac, Vulkan/DX12 elsewhere). Smooth, consistent everywhere. | | **Markdown editor** | Custom widget: `ropey` + `syntect` + `cosmic-text`. Live preview pane via `pulldown-cmark` rendering. | | **Code editor** | Same custom widget with Lua/Liquid/CSS language definitions via `syntect`. | | **Widgets needed** | Tree view, resizable panes, tabs, modals, toasts, forms — all buildable in iced, some exist in `iced_aw`. | | **Mac experience** | Native GPU, respects DPI, no foreign toolkit feel. cmd-key shortcuts, native-feeling scroll. | | **Distribution** | Single static binary. No external deps. ~15-25MB. | | **Risk** | Medium. Custom editor is the biggest piece. Iced ecosystem is growing but you build more yourself. | ### Path B: GTK4-rs + GtkSourceView (Fastest, Linux-best) | Aspect | Assessment | |--------|-----------| | **JS purity** | 100%. | | **Rendering** | Native GTK (Cairo/Vulkan). | | **Editors** | GtkSourceView — zero work, production-grade. | | **Widgets** | All built-in (TreeView, Paned, Notebook, etc.). | | **Mac experience** | 6/10. Functional but feels non-native. Requires GTK4 installed via Homebrew. | | **Distribution** | Requires GTK4 runtime on user machine (Mac/Windows). | | **Risk** | Low for functionality, medium-high for Mac UX polish. | --- ## Backend Subsystem Assessment (Green-Field) Since this is a rewrite, effort is for building clean, not porting messy. AI agents can generate verbose Rust boilerplate efficiently. ### 1. Database — Easy - **`rusqlite`** with `refinery` for migrations. Design schema fresh. - On-disc format preserved: Markdown + YAML frontmatter files. DB is for indexing/metadata only. - **Key crates:** `rusqlite`, `serde`, `serde_yaml`, `gray_matter` or manual YAML parsing - **Cost:** 2-3 weeks ### 2. Core Engine Layer — Medium - Fresh design with Rust idioms (traits, enums, Result). No need to mirror 43 TS classes. - **No WXR import** — dropped entirely. - **Key crates:** `pulldown-cmark` (Markdown), `liquid` (templates), `image` (thumbnails/WEBP), `git2` (Git, no LFS — shell out for LFS ops), `notify` (file watching), `uuid`, `serde_json` - **Cost:** 8-12 weeks ### 3. AI/LLM Integration — Easy ✅ (simplified) - **OpenAI-compatible endpoint only.** Single wire format (Chat Completions API). - Single-shot calls only (no streaming, no chat, no tool call loops). Used for: translation, image description, title generation. - **`reqwest`** + `serde_json` + OpenAI request/response structs. ~500 LOC. - Works with OpenCode Zen, local Ollama, any OpenAI-compatible proxy. - **Cost:** 1-2 weeks ### 4. Lua Scripting — Easy - **`mlua`** crate: embed Lua 5.4. Sandboxed, ~300KB. Expose engine APIs via `UserData` trait. - **Cost:** 2-3 weeks ### 5. Static Site Generation — Medium - `pulldown-cmark` → HTML, `liquid` templates, `rayon` for parallel generation - Pagefind CLI for search index (unchanged, it's a binary) - RSS/Atom/sitemap generation via `quick-xml` - **Cost:** 4-6 weeks ### 6. Publishing — Easy - SSH: `ssh2` crate. rsync: shell out to `rsync`. Git: `git2`. - **Cost:** 1-2 weeks ### 7. Embeddings & Similarity — Medium - `ort` (ONNX Runtime) for local embeddings. `usearch` Rust bindings for HNSW index. - **Cost:** 2-3 weeks ### 8. MCP Server — Optional (v2) - Deferred. Not needed for v1. - **Cost:** 0 weeks (v1) ### 9. Preview Server — Easy - `axum` HTTP server serving generated HTML + media. - **Cost:** 1-2 weeks ### 10. UI (Iced) — Hard (largest piece) - Custom editor widget: `ropey` + `syntect` + `cosmic-text` (4-6 weeks) - Application chrome: tree sidebar, tab bar, resizable panes, settings, modals (6-8 weeks) - Chat panel, AI integration UI (2-3 weeks) - Git diff view, validation views, import wizard (3-4 weeks) - **Cost:** 15-21 weeks ### 11. Tests — Medium - Rust `#[test]` + `mockall` for traits. AI agents generate test boilerplate well. - Test as you build (TDD per CLAUDE.md rules) - **Cost:** Folded into each subsystem (add ~40% to each estimate) --- ## What Gets Better (All Paths) 1. **Binary size:** 5-15MB vs 150-200MB 2. **Memory:** ~50-80% less RAM (no Chromium main process) 3. **Startup:** Significantly faster 4. **Generation perf:** `rayon` + `pulldown-cmark` + `liquid` = faster site generation 5. **Type safety:** Compile-time guarantees on everything 6. **Security:** Memory-safe, smaller supply-chain surface ## What Gets Worse (All Paths) 1. **Dev velocity:** Rust is slower to iterate than TypeScript 2. **AI SDK:** Maintain your own streaming multi-provider SDK 3. **Macro migration:** Existing user Python macros must be rewritten in Lua 4. **Talent pool:** Smaller contributor base --- ## Effort Summary (Green-Field with AI Agents) | Subsystem | Weeks (with tests) | |-----------|-------------------| | Database + on-disc format | 3-4 | | Core engines (posts, media, tags, projects) | 11-17 | | AI/LLM (single-shot, OpenAI-compat) | 1-2 | | Lua scripting | 3-4 | | Static site generation | 6-8 | | Publishing + Git | 2-3 | | Embeddings + search | 3-4 | | Preview server | 1-2 | | **UI (Iced)** | **21-29** | | Integration + polish | 4-6 | | **Total** | **55-79 person-weeks** | Compared to original estimate (76-103 weeks): **dropping WXR import, streaming chat, multi-provider AI, and MCP server saves ~20 weeks.** With AI agents running 2-3 parallel workstreams: **4-8 months** of active sessions. --- ## Recommended Architecture: Iced + Rust ``` bds-rust/ ├── crates/ │ ├── bds-core/ # Domain types, traits, on-disc format (Markdown+YAML) │ ├── bds-db/ # SQLite layer (rusqlite + refinery migrations) │ ├── bds-engine/ # Business logic (posts, media, tags, projects, generation) │ ├── bds-ai/ # Multi-provider LLM client (streaming, tool calls) │ ├── bds-lua/ # Lua scripting runtime (mlua) │ ├── bds-git/ # Git operations (git2 + LFS shell-out) │ ├── bds-publish/ # SSH/rsync deployment │ ├── bds-search/ # Embeddings (ort) + similarity (usearch) + pagefind │ ├── bds-mcp/ # MCP server │ ├── bds-preview/ # HTTP preview server (axum) │ └── bds-editor/ # Syntax-highlighting editor widget (ropey+syntect+cosmic-text) ├── src/ # Iced application (UI, state, views) ├── assets/ # Icons, themes └── Cargo.toml # Workspace ``` **Key Rust crates:** | Purpose | Crate | |---------|-------| | GUI framework | `iced` | | Text buffer | `ropey` | | Syntax highlighting | `syntect` | | Text layout | `cosmic-text` | | Database | `rusqlite` | | Migrations | `refinery` | | Markdown → HTML | `pulldown-cmark` | | Templates | `liquid` | | YAML frontmatter | `serde_yaml` | | Image processing | `image` | | HTTP server (preview) | `axum` | | HTTP client (AI) | `reqwest` | | Git | `git2` | | SSH | `ssh2` | | File watching | `notify` | | Lua scripting | `mlua` | | ONNX inference | `ort` | | Vector search | `usearch` | | Async runtime | `tokio` | | Parallelism | `rayon` | | Serialization | `serde` + `serde_json` | | UUID | `uuid` | | Error handling | `thiserror` + `anyhow` | --- ## Verdict **Feasible: Yes.** With the constraints resolved (no WYSIWYG, Lua instead of Python, green-field, AI agents, no timeline): - Every subsystem has proven Rust crate equivalents - The hardest piece is the custom editor widget (~4-6 weeks) and AI streaming client (~5-7 weeks) - Iced gives Mac-first cross-platform GUI without GTK's foreign feel or any JS runtime - Single static binary, ~15-25MB, zero external dependencies - AI agents are well-suited to Rust's verbose but structured patterns **The main risk** is Iced's maturity (6/10). It's real software backing a real desktop environment (COSMIC), but the widget ecosystem is young. You will build things that React gave you for free. With AI agents and no deadline, this is acceptable. --- ## Remaining Questions 1. Confirm Iced vs GTK4-rs preference? (Iced = better Mac, more custom work. GTK = more widgets, worse Mac feel.) 2. Which AI providers are must-have? (Anthropic + OpenAI + Ollama? Or all 5?) 3. Should the MCP server remain, or is it optional for v1? 4. Is WordPress WXR import a v1 requirement?