Crate rnk

Crate rnk 

Source
Expand description

§rnk - React-like Terminal UI for Rust

A terminal UI framework inspired by Ink and Bubbletea.

§Features

  • Declarative UI with flexbox layout
  • Reactive state management with hooks
  • Keyboard and mouse input handling
  • ANSI color and style support
  • Inline mode (default): Output persists in terminal history
  • Fullscreen mode: Uses alternate screen buffer
  • Cross-thread render requests for async/multi-threaded apps
  • Runtime mode switching between inline and fullscreen
  • Println for persistent messages above the UI

§Quick Start

use rnk::prelude::*;

fn main() -> std::io::Result<()> {
    render(app).run()
}

fn app() -> Element {
    Box::new()
        .padding(1)
        .child(Text::new("Hello, rnk!").bold().into_element())
        .into_element()
}

§Render Modes

§Inline Mode (Default)

Output appears at the current cursor position and persists in terminal history. This is the default mode, matching Ink and Bubbletea’s behavior.

render(app).run()?;           // Inline mode (default)
render(app).inline().run()?;  // Explicit inline mode

§Fullscreen Mode

Uses the alternate screen buffer. Content is cleared when the app exits.

render(app).fullscreen().run()?;

§Runtime Mode Switching

Switch between modes at runtime (like Bubbletea):

let app = use_app();

use_input(move |key| {
    if key == Key::Char(' ') {
        if app.is_alt_screen() {
            app.exit_alt_screen();  // Switch to inline
        } else {
            app.enter_alt_screen(); // Switch to fullscreen
        }
    }
});

§Println for Persistent Messages

In inline mode, use println() to output messages above the UI:

use rnk::println;

// In an input handler
rnk::println("Task completed!");
rnk::println(format!("Downloaded {} files", count));

// Or via AppContext
let app = use_app();
app.println("Another message");

§Cross-Thread Rendering

When updating state from a background thread, use request_render() to notify the UI to refresh:

use std::thread;
use std::sync::{Arc, RwLock};
use rnk::request_render;

let state = Arc::new(RwLock::new(0));
let state_clone = Arc::clone(&state);

thread::spawn(move || {
    *state_clone.write().unwrap() += 1;
    request_render(); // Notify rnk to re-render
});

Re-exports§

pub use crate::components::Box;
pub use crate::components::Text;
pub use crate::core::Color;
pub use crate::core::Element;
pub use crate::core::ElementId;
pub use crate::core::Style;
pub use crate::renderer::AppBuilder;
pub use crate::renderer::AppOptions;
pub use crate::renderer::IntoPrintable;
pub use crate::renderer::ModeSwitch;
pub use crate::renderer::Printable;
pub use crate::renderer::RenderHandle;
pub use crate::renderer::enter_alt_screen;
pub use crate::renderer::exit_alt_screen;
pub use crate::renderer::is_alt_screen;
pub use crate::renderer::println;
pub use crate::renderer::println_trimmed;
pub use crate::renderer::render;
pub use crate::renderer::render_fullscreen;
pub use crate::renderer::render_handle;
pub use crate::renderer::render_inline;
pub use crate::renderer::render_to_string;
pub use crate::renderer::render_to_string_auto;
pub use crate::renderer::render_to_string_no_trim;
pub use crate::renderer::request_render;

Modules§

components
UI Components
core
Core types and abstractions
hooks
Hooks system for reactive state management
layout
Layout system using Taffy
prelude
Prelude module - commonly used imports
renderer
Rendering system
runtime
Runtime utilities for terminal state management
testing
Testing utilities for verifying UI components Testing infrastructure for Tink

Macros§

golden_test
Macro for creating golden tests