<p align="center">
<img src="https://raw.githubusercontent.com/moltenlabs/rune/main/.github/assets/banner.png" alt="Rune" width="100%" />
</p>
<h1 align="center">🪄 Rune</h1>
<p align="center">
<strong>Shell glamour - beautiful prompts and output for scripts.</strong>
</p>
<p align="center">
<a href="https://crates.io/crates/rune"><img src="https://img.shields.io/crates/v/rune.svg?style=flat-square&logo=rust" alt="Crates.io"></a>
<a href="https://docs.rs/rune"><img src="https://img.shields.io/docsrs/rune?style=flat-square&logo=docs.rs" alt="Documentation"></a>
<a href="https://github.com/moltenlabs/rune/actions"><img src="https://img.shields.io/github/actions/workflow/status/moltenlabs/rune/ci.yml?style=flat-square&logo=github" alt="CI"></a>
<a href="#license"><img src="https://img.shields.io/badge/license-MIT%2FApache--2.0-blue?style=flat-square" alt="License"></a>
</p>
<p align="center">
<a href="#features">Features</a> •
<a href="#installation">Installation</a> •
<a href="#usage">Usage</a> •
<a href="#cli">CLI</a>
</p>
---
## What is Rune?
**Rune** is the Rust equivalent of [gum](https://github.com/charmbracelet/gum) from Charmbracelet. It provides beautiful interactive prompts and styled output for shell scripts and CLI applications.
<p align="center">
<img src="https://raw.githubusercontent.com/moltenlabs/rune/main/.github/assets/demo.gif" alt="Rune Demo" width="600" />
</p>
---
## Features
<table>
<tr>
<td width="50%">
### 📝 Input
Get text input with style.
```rust
use rune::input;
let name = input("What's your name?")
.placeholder("Enter name...")
.default("World")
.run();
println!("Hello, {}!", name);
```
</td>
<td width="50%">
### ✅ Confirm
Yes/no confirmations.
```rust
use rune::confirm;
if confirm("Continue?")
.default(true)
.run()
{
println!("Proceeding...");
}
```
</td>
</tr>
<tr>
<td width="50%">
### 📋 Choose
Select from a list.
```rust
use rune::choose;
let choice = choose(&[
"Option A",
"Option B",
"Option C",
])
.header("Pick one:")
.run();
if let Some(c) = choice {
println!("You chose: {}", c);
}
```
</td>
<td width="50%">
### 🔍 Filter
Fuzzy search through options.
```rust
use rune::filter;
let result = filter(&[
"apple", "banana", "cherry",
"date", "elderberry",
])
.header("Search fruits:")
.limit(5)
.run();
```
</td>
</tr>
<tr>
<td width="50%">
### 🔄 Spin
Show spinners while working.
```rust
use rune::spin;
spin("Loading data...")
.run(|| {
// Do work here
std::thread::sleep_ms(2000);
});
// ✓ Loading data...
```
</td>
<td width="50%">
### 🎨 Style
Style arbitrary text.
```rust
use rune::style_text;
use lacquer::Border;
style_text("Hello!")
.foreground_hex("#F97316")
.bold()
.padding(1, 2)
.border(Border::Rounded)
.print();
```
</td>
</tr>
</table>
---
## Installation
### As a library
```bash
cargo add rune
```
### As a CLI tool
```bash
cargo install rune
```
---
## CLI Usage
Rune also works as a standalone CLI tool for shell scripts:
### Input
```bash
NAME=$(rune input --prompt "Name:" --placeholder "Enter name...")
echo "Hello, $NAME"
```
### Confirm
```bash
if rune confirm "Deploy to production?"; then
./deploy.sh
fi
```
### Choose
```bash
CHOICE=$(rune choose "Development" "Staging" "Production" --header "Select environment:")
echo "Deploying to $CHOICE"
```
### Filter
```bash
FILE=$(rune filter *.rs --header "Select a file:")
code "$FILE"
```
### Spin
```bash
rune spin "Installing dependencies..." --duration 5
```
### Style
```bash
rune style "Success!" --foreground "#10B981" --bold
rune style "Warning" --foreground "#F59E0B" --border rounded --padding "1,2"
```
---
## Shell Script Example
```bash
#!/bin/bash
# Welcome message
rune style "🪄 Setup Wizard" --foreground "#F97316" --bold
# Get project name
PROJECT=$(rune input --prompt "Project name:" --placeholder "my-project")
# Choose template
TEMPLATE=$(rune choose "web" "cli" "library" --header "Select template:")
# Confirm
if rune confirm "Create $PROJECT using $TEMPLATE template?"; then
rune spin "Creating project..." --duration 2
rune style "✓ Project created!" --foreground "#10B981" --bold
else
rune style "Cancelled" --foreground "#EF4444"
fi
```
---
## API Reference
### Input
```rust
input("Prompt")
.placeholder("hint") // Placeholder text
.default("value") // Default value
.password() // Hide input
.char_limit(100) // Max characters
.header("Header") // Header text
.run()
```
### Confirm
```rust
confirm("Question?")
.default(true) // Default answer
.affirmative("Yes") // Yes text
.negative("No") // No text
.run()
```
### Choose
```rust
choose(&options)
.header("Title") // Header text
.cursor("> ") // Selection cursor
.limit(10) // Visible items
.run()
```
### Filter
```rust
filter(&options)
.header("Search") // Header text
.placeholder("Type...") // Input placeholder
.limit(10) // Visible items
.run()
```
### Spin
```rust
spin("Message")
.style(SpinnerStyle::Dots) // Spinner style
.color(Color::Cyan) // Spinner color
.run(|| { /* work */ })
```
---
## Ecosystem
Rune is part of the **Molten Labs** open source ecosystem:
| **[molten_brand](https://crates.io/crates/molten_brand)** | Design tokens & colors |
| **[glyphs](https://crates.io/crates/glyphs)** | ANSI escape sequences |
| **[lacquer](https://crates.io/crates/lacquer)** | Terminal styling |
| **[cauldron](https://crates.io/crates/cauldron)** | TUI framework |
| **[sparks](https://crates.io/crates/sparks)** | TUI components |
| **[rune](https://crates.io/crates/rune)** | Shell glamour (you are here) |
| **ember** | Markdown renderer |
| **smelt** | Pretty logging |
---
## Why "Rune"?
Runes are ancient symbols of magic and power. With Rune, you inscribe beautiful, interactive spells into your shell scripts. 🪄
---
## Contributing
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
---
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))
at your option.
---
<p align="center">
<sub>Built with 🪄 by <a href="https://github.com/moltenlabs">Molten Labs</a></sub>
</p>