{"id":35458445,"url":"https://github.com/hawk90/revue","last_synced_at":"2026-04-04T06:15:55.467Z","repository":{"id":331443223,"uuid":"1128560551","full_name":"hawk90/revue","owner":"hawk90","description":"Modern reactive TUI framework for Rust — signals, effects, and beautiful widgets","archived":false,"fork":false,"pushed_at":"2026-03-31T16:02:58.000Z","size":50873,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-31T16:07:44.449Z","etag":null,"topics":["reactive","rust","rust-tui","signals","tui"],"latest_commit_sha":null,"homepage":"https://hawk90.github.io/revue/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hawk90.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["hawk90"]}},"created_at":"2026-01-05T20:28:39.000Z","updated_at":"2026-03-31T16:02:30.000Z","dependencies_parsed_at":"2026-02-01T11:01:32.059Z","dependency_job_id":null,"html_url":"https://github.com/hawk90/revue","commit_stats":null,"previous_names":["hawk90/revue"],"tags_count":158,"template":false,"template_full_name":null,"purl":"pkg:github/hawk90/revue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawk90%2Frevue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawk90%2Frevue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawk90%2Frevue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawk90%2Frevue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hawk90","download_url":"https://codeload.github.com/hawk90/revue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hawk90%2Frevue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["reactive","rust","rust-tui","signals","tui"],"created_at":"2026-01-03T07:20:06.135Z","updated_at":"2026-04-01T18:05:15.731Z","avatar_url":"https://github.com/hawk90.png","language":"Rust","funding_links":["https://github.com/sponsors/hawk90"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/banner.svg\" alt=\"Revue\" width=\"480\"\u003e\n\n**/rɪˈvjuː/** — *Re + Vue* — A Vue-style TUI framework for Rust\n\n[![crates.io](https://img.shields.io/crates/v/revue?style=for-the-badge\u0026logo=rust\u0026logoColor=white\u0026color=orange)](https://crates.io/crates/revue)\n[![docs.rs](https://img.shields.io/docsrs/revue?style=for-the-badge\u0026logo=docs.rs\u0026logoColor=white)](https://docs.rs/revue)\n[![GitHub Stars](https://img.shields.io/github/stars/hawk90/revue?style=for-the-badge\u0026logo=github)](https://github.com/hawk90/revue/stargazers)\n\n[![CI](https://img.shields.io/github/actions/workflow/status/hawk90/revue/ci.yml?style=flat-square\u0026label=CI)](https://github.com/hawk90/revue/actions/workflows/ci.yml)\n[![codecov](https://img.shields.io/codecov/c/github/hawk90/revue?style=flat-square\u0026logo=codecov\u0026logoColor=white)](https://codecov.io/gh/hawk90/revue)\n[![license](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)\n[![Rust 1.87+](https://img.shields.io/badge/MSRV-1.87%2B-orange?style=flat-square\u0026logo=rust)](https://www.rust-lang.org)\n[![downloads](https://img.shields.io/crates/d/revue?style=flat-square\u0026label=downloads\u0026color=blue)](https://crates.io/crates/revue)\n\n[Quick Start](#quick-start) · [Tutorials](docs/tutorials/) · [Examples](examples/) · [Documentation](docs/) · [Contributing](CONTRIBUTING.md)\n\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n## Why Revue?\n\n\u003e Build terminal UIs like you build web apps — with **CSS** and **reactive state**.\n\n- **CSS Styling** — Write styles in familiar CSS syntax with variables, selectors, and animations\n- **Reactive State** — Vue-inspired `Signal`/`Computed`/`Effect` system for automatic UI updates\n- **100+ Widgets** — Rich component library: inputs, tables, charts, markdown, images, and more\n- **Hot Reload** — See CSS changes instantly without restarting your app\n- **Developer Tools** — Widget inspector, snapshot testing, and performance profiler built-in\n- **Single Binary** — Pure Rust, no runtime dependencies, blazing fast\n\n\u003cbr\u003e\n\n## Quick Start\n\n```bash\ncargo add revue\n```\n\n```rust\nuse revue::prelude::*;\n\nfn main() -\u003e Result\u003c()\u003e {\n    let mut app = App::builder()\n        .style(\"styles.css\")\n        .build();\n\n    let counter = Counter::new();\n    app.run(counter, |event, counter, _app| {\n        if let Event::Key(key) = event {\n            counter.handle_key(\u0026key.key)\n        } else {\n            false\n        }\n    })\n}\n\nstruct Counter {\n    count: Signal\u003ci32\u003e,\n}\n\nimpl Counter {\n    fn new() -\u003e Self {\n        Self { count: signal(0) }\n    }\n\n    fn handle_key(\u0026mut self, key: \u0026Key) -\u003e bool {\n        match key {\n            Key::Up =\u003e { self.count.update(|n| *n += 1); true }\n            Key::Down =\u003e { self.count.update(|n| *n -= 1); true }\n            _ =\u003e false,\n        }\n    }\n}\n\nimpl View for Counter {\n    fn render(\u0026self, ctx: \u0026mut RenderContext) {\n        let count = self.count.get();\n        vstack()\n            .class(\"container\")\n            .child(Text::new(format!(\"Count: {}\", count)).bold())\n            .child(\n                hstack().gap(1)\n                    .child(Text::new(\"↑/↓ to change, q to quit\"))\n            )\n            .render(ctx);\n    }\n}\n```\n\n```css\n/* styles.css */\n.container {\n    padding: 2;\n    gap: 1;\n    border: rounded cyan;\n    align-items: center;\n}\n\nbutton {\n    padding: 0 2;\n    background: var(--primary);\n}\n\nbutton:hover {\n    background: var(--primary-dark);\n}\n```\n\n\u003cbr\u003e\n\n## Key Features\n\n### Reactive Forms\n\nAutomatic validation with type-safe form state:\n\n```rust\nuse revue::patterns::form::FormState;\n\nlet form = FormState::new()\n    .field(\"email\", |f| f\n        .label(\"Email\")\n        .email()\n        .required())\n    .field(\"password\", |f| f\n        .label(\"Password\")\n        .password()\n        .min_length(8))\n    .field(\"confirm\", |f| f\n        .label(\"Confirm Password\")\n        .password()\n        .matches(\"password\"))\n    .build();\n\n// Reactive validation - errors auto-update when values change\nform.set_value(\"email\", \"invalid\");\nassert!(!form.is_valid());\n\nform.set_value(\"email\", \"user@example.com\");\n// Validation automatically recalculates\n```\n\nSee [Forms Tutorial](docs/tutorials/06-forms.md) for complete guide.\n\n### Animation System\n\nRich animations with easing functions and keyframes:\n\n```rust\nuse revue::animation::{Animation, Easing};\n\n// Fade in with custom easing\ntext(\"Hello!\")\n    .animation(Animation::fade_in()\n        .duration(300)\n        .easing(Easing::EaseInOutCubic))\n\n// Slide in from left\ntext(\"Welcome!\")\n    .animation(Animation::slide_in_left()\n        .duration(500)\n        .delay(100))\n\n// Keyframe animation\ntext(\"Pulsing!\")\n    .animation(Animation::keyframe(|keyframes| {\n        keyframes\n            .at(0, |kf| kf.scale(1.0).opacity(1.0))\n            .at(50, |kf| kf.scale(1.2).opacity(0.8))\n            .at(100, |kf| kf.scale(1.0).opacity(1.0))\n    }))\n```\n\n### Worker Pool\n\nExecute background tasks without blocking the UI:\n\n```rust\nuse revue::worker::{WorkerHandle, WorkerPool};\n\n// Spawn blocking task\nlet handle = WorkerHandle::spawn_blocking(|| {\n    heavy_computation()\n});\n\n// Use worker pool\nlet pool = WorkerPool::new(4);\npool.submit(|| {\n    fetch_data_from_api()\n});\n\n// Get result when ready\nif let Some(result) = handle.try_recv() {\n    // Update UI with result\n}\n```\n\n### Hot Reload\n\nCSS changes update instantly without restart:\n\n```rust\nlet mut app = App::builder()\n    .style(\"styles.css\")\n    .hot_reload(true)  // Enable hot reload\n    .build();\n\napp.run(view, handler)?;\n```\n\nEdit `styles.css` and see changes immediately - no restart needed!\n\n### DevTools\n\nBuilt-in widget inspector and profiler:\n\n```rust\nlet mut app = App::builder()\n    .devtools(true)  // Enable devtools\n    .build();\n\napp.run(view, handler)?;\n```\n\n**Keyboard shortcuts:**\n- `Ctrl+D` — Toggle devtools overlay\n- `Ctrl+I` — Open widget inspector\n\n**Features:**\n- Widget inspector with computed styles\n- Performance profiler for identifying bottlenecks\n- Snapshot testing for UI regression testing\n\n\u003cbr\u003e\n\n## Widgets\n\n| Category | Components |\n|:---------|:-----------|\n| **Layout** | `vstack` `hstack` `grid` `scroll` `tabs` `accordion` `splitter` `layers` |\n| **Input** | `input` `textarea` `select` `checkbox` `radio` `switch` `slider` `number_input` |\n| **Forms** | `form` `form_field` — Built-in validation system |\n| **Display** | `text` `markdown` `table` `tree` `list` `progress` `badge` `image` `presentation` |\n| **Feedback** | `modal` `toast` `notification` `tooltip` `popover` `alert` `callout` |\n| **Charts** | `barchart` `line_chart` `sparkline` `heatmap` `gauge` `boxplot` `histogram` |\n| **Advanced** | `rich_text_editor` `json_viewer` `csv_viewer` `diagram` `command_palette` |\n| **Dev** | `debug_overlay` `snapshot_test` `profiler` |\n\n\u003e **100+ Widgets** — See [FEATURES.md](docs/FEATURES.md) for complete catalog\n\n\u003cbr\u003e\n\n## Examples\n\n```bash\n# Basics\ncargo run --example counter       # Reactive counter with Signal\ncargo run --example todo          # Full-featured todo app\ncargo run --example hello_world   # Minimal \"Hello World\"\n\n# UI Components\ncargo run --example form_validation  # Form validation demo\ncargo run --example dashboard     # Charts and data widgets\ncargo run --example gallery       # Widget showcase\n\n# Advanced\ncargo run --example animations    # Animation system\ncargo run --example worker_basic  # Background tasks\ncargo run --example slideshow     # Terminal presentations\ncargo run --example ide           # Rich text editor\n\n# Real-world\ncargo run --example chat          # Multi-user chat\ncargo run --example data_explorer # JSON/CSV viewer\n```\n\nBrowse all examples in the [examples/](examples/) directory.\n\n\u003cbr\u003e\n\n## Tutorials\n\n| Tutorial | Description | Time |\n|:---------|:------------|:-----|\n| [Getting Started](docs/tutorials/01-getting-started.md) | Install and create your first app | 5 min |\n| [Counter App](docs/tutorials/02-counter.md) | Learn state management with signals | 10 min |\n| [Todo App](docs/tutorials/03-todo.md) | Build a full-featured todo list | 20 min |\n| [Reactive State](docs/tutorials/04-reactive.md) | Deep dive into Signal, Computed, Effect | 15 min |\n| [Styling](docs/tutorials/05-styling.md) | CSS styling and theming | 15 min |\n| [Forms](docs/tutorials/06-forms.md) | Form handling with validation | 20 min |\n\n\u003cbr\u003e\n\n## Guides\n\n| Guide | Description |\n|:------|:------------|\n| [App Builder](docs/guides/app-builder.md) | Complete App Builder API reference |\n| [Styling](docs/guides/styling.md) | CSS properties, selectors, and theming |\n| [State Management](docs/guides/state.md) | Reactive state with signals |\n| [Testing](docs/guides/testing.md) | Test your TUI apps |\n| [Accessibility](docs/guides/accessibility.md) | Build inclusive apps |\n| [Performance](docs/guides/performance.md) | Optimization tips |\n| [Plugin System](docs/guides/plugins.md) | Create and use plugins |\n\n\u003cbr\u003e\n\n## Comparison\n\n| | Revue | ratatui | reratui | Cursive | Textual |\n|:--|:--:|:--:|:--:|:--:|:--:|\n| **Type** | Framework | Library | Framework | Framework | Framework |\n| **Language** | Rust | Rust | Rust | Rust | Python |\n| **Architecture** | Retained | Immediate | Immediate | Retained | Retained |\n| **Styling** | CSS Files | Inline | Inline-style | TOML | CSS |\n| **State** | Signals | Manual | Hooks | Event | Reactive |\n| **Widgets** | 100+ | 15 built-in | Components | 40+ | 35+ |\n| **Layout** | Flex+Grid | Constraint | Flex | Dock | Dock+Grid |\n| **Forms** | ✅ Built-in | ❌ | ❌ | ❌ | ✅ |\n| **Animation** | ✅ Tween+Keyframes | ❌ | ❌ | ❌ | ✅ |\n| **Worker Pool** | ✅ | ❌ | ❌ | ❌ | ❌ |\n| **Hot Reload** | ✅ | ❌ | ❌ | ❌ | ✅ |\n| **Devtools** | ✅ | ❌ | ❌ | ❌ | ✅ |\n| **Single Binary** | ✅ | ✅ | ✅ | ✅ | ❌ |\n\n\u003e **Note**: [ratatui](https://crates.io/crates/ratatui) is a low-level TUI library (like React's DOM), while [reratui](https://crates.io/crates/reratui) is a React-like framework built on top of ratatui. See [Framework Comparison](docs/FRAMEWORK_COMPARISON.md#11-ratatui-vs-reratui-which-one-to-choose) for detailed analysis.\n\n\u003cbr\u003e\n\n## Documentation\n\n- **[Getting Started](docs/tutorials/01-getting-started.md)** — 5-minute tutorial\n- **[Widget Catalog](docs/FEATURES.md)** — Complete widget reference\n- **[App Builder Guide](docs/guides/app-builder.md)** — Complete App Builder API reference\n- **[Styling Guide](docs/guides/styling.md)** — CSS properties and theming\n- **[State Management](docs/guides/state.md)** — Signals, Computed, Effects\n- **[API Reference](https://docs.rs/revue)** — Full API documentation\n- **[Architecture](docs/ARCHITECTURE.md)** — System design\n\n\u003cbr\u003e\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n```bash\ngit clone https://github.com/hawk90/revue.git\ncd revue \u0026\u0026 cargo test\n```\n\n**Development workflow:**\n1. Fork the repository\n2. Create a feature branch (`feat/your-feature`, `fix/your-bug`)\n3. Make your changes with tests\n4. Run `cargo test` and `cargo clippy`\n5. Submit a pull request\n\n\u003cbr\u003e\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n\u003cdiv align=\"center\"\u003e\n\u003cbr\u003e\n\n**[↑ Back to Top](#why-revue)**\n\n[crates.io](https://crates.io/crates/revue) · [docs.rs](https://docs.rs/revue) · [GitHub](https://github.com/hawk90/revue)\n\n\u003csub\u003eBuilt with Rust\u003c/sub\u003e\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawk90%2Frevue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhawk90%2Frevue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawk90%2Frevue/lists"}