Skip to main content

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;
pub use crate::renderer::render_to_string_auto;
pub use crate::renderer::render_to_string_no_trim;
pub use crate::renderer::request_render;

Modules§

animation
Animation system
cmd
Command System for managing side effects
components
UI Components
core
Core types and abstractions
hooks
Hooks system for reactive state management
layout
Layout system using Taffy
macros
Declarative UI macros for rnk
prelude
Prelude module - commonly used imports
reconciler
Reconciliation system for efficient UI updates
renderer
Rendering system
runtime
Runtime utilities for terminal state management
testing
Testing utilities for verifying UI components Testing infrastructure for Tink

Macros§

box_element
Create a Box element with children
col
Create a vertical column layout (flex-direction: column)
golden_test
Macro for creating golden tests
list
Create a list of elements from an iterator
list_indexed
Create a list of elements with index from an iterator
row
Create a horizontal row layout (flex-direction: row)
spacer
Create a Spacer element
styled_text
Create a styled Text element
text
Create a Text element
when
Conditional rendering helper