streamlit-macros

Crates.iostreamlit-macros
lib.rsstreamlit-macros
version0.1.1
created_at2026-01-06 04:37:05.797385+00
updated_at2026-01-06 04:37:05.797385+00
descriptionStreamlit - A faster way to build and share data apps.
homepage
repositoryhttps://github.com/killf/streamlit-rust
max_upload_size
id2025177
size13,504
killf (killf)

documentation

README

Streamlit Rust Backend

A pure Rust implementation of Streamlit backend with WebSocket support, compatible with the official Streamlit frontend.

Features

  • 🦀 Pure Rust - No Python dependencies, completely written in Rust
  • 🚀 High Performance - Leverages Rust's performance and safety features
  • 🔄 WebSocket Compatible - Compatible with official Streamlit frontend
  • 🎨 Python-like API - Familiar Streamlit syntax (st.write(), st.button(), etc.)
  • 🔧 Extensible - Easy to add new widgets and components
  • 📦 Modern Dependencies - Uses latest versions of actix-web, tokio, and other crates

Project Structure

This is a Cargo workspace with the following members:

streamlit-rust/
├── streamlit/          # Main library crate
│   ├── src/
│   │   ├── api.rs          # Streamlit API implementation
│   │   ├── server.rs       # HTTP and WebSocket server
│   │   ├── elements/       # UI element implementations
│   │   ├── websocket/      # WebSocket handlers
│   │   ├── error.rs        # Error types
│   │   └── lib.rs          # Public API
│   └── examples/           # Example applications
└── streamlit-macros/   # Procedural macros (#[main])

Quick Start

Running Examples

The easiest way to try out streamlit-rust is to run the included examples:

# Run the basic example
cargo run --example basic

# Run the hello world example
cargo run --example hello

# Run the timer example
cargo run --example timer

# Run the container/columns example
cargo run --example container

The server will start on http://localhost:8501 by default.

Basic Usage

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    // Set page title
    st.title("Hello from Rust!");

    // Write some text
    st.write("This is a demonstration of Streamlit in Rust.");

    // Display code
    st.code("fn main() { println!(\"Hello, world!\"); }", "rust");

    // Add a button
    if st.button("Click me!") {
        st.write("Button was clicked!");
    }
}

API Endpoints

  • WebSocket: ws://localhost:8501/_stcore/stream - Main WebSocket connection
  • Health Check: GET /_stcore/health - Server status
  • Run Script: POST /api/run - Execute Rust code
  • Index: GET / - Basic info page

Available Components

Text Display

  • st.write(content) - Plain text (supports markdown)
  • st.title(content) / st.h1(content) - Title (h1)
  • st.header(content) / st.h2(content) - Header (h2)
  • st.sub_header(content) / st.h3(content) - Sub-header (h3)
  • st.markdown(content) - Markdown content with extended options
  • st.caption(content) - Small caption text
  • st.badge(label) - Badge/icon component

Code Display

  • st.code(code, language) - Syntax-highlighted code block
  • CodeOptions::new(code, language) - Advanced code display options
    • .line_numbers(bool) - Show line numbers
    • .wrap_lines(bool) - Wrap long lines
    • .height(...) - Set height
    • .width(...) - Set width

Layout Components

  • st.container() - Container for grouping elements
  • st.container_options(...) - Container with options
    • .border(bool) - Show border
    • .horizontal(bool) - Horizontal layout
    • .gap(...) - Set gap size
    • .alignment(...) - Set alignment
  • st.columns(n) - Create N columns
  • st.columns([v1, v2, ...]) - Create columns with custom weights
  • ColumnsOptions::new(...) - Advanced column options

Interactive Components

  • st.button(label) - Button (returns true if clicked)
  • st.button_options(...) - Button with options
    • .key(...) - Unique key
    • .help(...) - Help tooltip
    • .type(...) - Button type (primary/secondary)
    • .icon(...) - Icon
    • .disabled(bool) - Disable button
    • .shortcut(...) - Keyboard shortcut

Utility Components

  • st.divider() - Horizontal divider
  • st.divider_options(...) - Custom divider width

Architecture

┌─────────────────┐    ┌─────────────────┐
│  Streamlit      │    │  Streamlit      │
│  Frontend       │◄──►│  Rust Backend   │
│  (JavaScript)    │    │  (WebSocket)     │
└─────────────────┘    └─────────────────┘
  1. Frontend: Official Streamlit frontend connects via WebSocket
  2. Backend: Rust server processes widget requests and sends responses
  3. Protocol: Compatible with official Streamlit WebSocket protocol

Development

Prerequisites

  • Rust 2024 edition or later
  • Cargo

Building

# Build the workspace
cargo build

# Build with optimizations
cargo build --release

Running Tests

cargo test

Formatting

cargo fmt

Examples

Hello World

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.write("Hello world!");
}

Markdown and Headers

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.title("🚀 Streamlit Rust Examples");
    st.header("Welcome to Streamlit in Rust!");
    st.sub_header("This is a sub-header");

    st.markdown(
        "You can use **bold text**, *italic text*, and `inline code` in markdown.\n\n\
        - Bullet point 1\n\
        - Bullet point 2\n\
        - Bullet point 3",
    );
}

Code Display

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.header("Code Examples");

    st.sub_header("Rust Code");
    st.code(
        "fn main() {
            println!(\"Hello, Streamlit!\");
        }",
        "rust",
    );

    st.sub_header("Python Code with line numbers");
    st.code_options(
        CodeOptions::new(
            "import streamlit as st\n\nst.write(\"Hello from Python!\")",
            "python",
        )
        .line_numbers(true),
    );
}

Layout with Containers and Columns

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.title("Container and Columns");

    st.write("Content outside container");

    // Container with border
    let container = st.container_options(ContainerOptions::new().border(true));
    container.write("Inside container");
    container.write("Also inside container");

    st.write("Back to main content");

    // Create columns
    if let [col1, col2, col3] = st.columns([1, 2, 1]) {
        col1.write("Left column (narrow)");
        col2.write("Middle column (wide)");
        col3.write("Right column (narrow)");
    }
}

Buttons and Interactions

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.title("Button Examples");

    // Simple button
    if st.button("Click me!") {
        st.write("Button was clicked!");
    }

    // Button with options
    if st.button_options(
        ButtonOptions::new("Primary Action")
            .icon("🚀")
            .help("This is a helpful tooltip"),
    ) {
        st.write("Primary action triggered!");
    }

    // Multiple buttons in columns
    if let [col1, col2, col3] = st.columns(3) {
        if col1.button("Button 1") {
            col1.write("Clicked 1");
        }
        if col2.button("Button 2") {
            col2.write("Clicked 2");
        }
        if col3.button("Button 3") {
            col3.write("Clicked 3");
        }
    }
}

Badge and Caption

use streamlit::*;

#[main]
async fn main(st: &Streamlit) {
    st.title("Badges and Captions");

    st.badge(BadgeOptions::new("Home").color("red").icon("🏠"));
    st.badge(BadgeOptions::new("Active").color("green").icon("✅"));
    st.badge(BadgeOptions::new("Warning").color("orange").icon("⚠️"));

    st.write("Some content here");

    st.caption("This is a small caption text below the content");
}

Compatibility

This implementation is designed to be compatible with:

  • ✅ Official Streamlit frontend
  • ✅ WebSocket protocol
  • ✅ Standard Streamlit widgets and layout components
  • 🔄 More widgets (slider, text_input, checkbox, etc.) - planned
  • 🔄 Session management - planned
  • 🔄 Advanced features - planned

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add your improvements
  4. Ensure tests pass (cargo test)
  5. Send a pull request

License

Apache License 2.0 - see LICENSE file for details.

Acknowledgments

  • Official Streamlit team for the amazing frontend and protocol
  • Rust community for excellent web framework support
  • actix-web and actix-ws maintainers for the solid WebSocket implementation
Commit count: 4

cargo fmt