Pjdur
October 31, 2025, 9:47am
1
cliux is a lightweight Rust crate for styling terminal output — no TUI required. It’s a toolkit for making CLI output look clean, expressive, and readable using structured components.
I built cliux because the output in one of my Rust projects felt flat and hard to scan. So I created a crate that adds layout and clarity without needing a full TUI framework.
Features
Boxed — bordered containers with titles and content
Section — titled blocks with horizontal dividers
Divider — customizable horizontal lines
.wrap() — wraps long text to fit the width
.pad() — emoji-aware padding for alignment
Example
use cliux::Boxed;
fn main() {
Boxed::new("Cliux Boxed")
.content("This code uses the cliux library to create a boxed section.")
.width(61)
.print();
}
Output:
Links
Github Repo
Crates.io
Any feedback, ideas, or contributions are welcome!
Pjdur
October 31, 2025, 11:36am
2
Restored this, open to hear what people think.
Pjdur
November 1, 2025, 8:22am
3
cliux v0.2.0 has been released, with a Label component and styles using ansi_term.
Example:
use cliux::Label;
fn main() {
Label::new("INFO").style("info").print();
Label::new("✓ Done").style("success").print();
Label::new("ERROR").style("error").print();
let inline = Label::new("DEBUG").color("cyan").bold(true).inline();
println!("Inline label: {}", inline);
}
Output:
Suggestions for more components or features are welcome.
Pjdur
November 5, 2025, 11:16am
4
cliux v0.3.0 has been released, with two new components: Tag and List.
Tag lets you display inline status markers like (beta) or {admin} with color and style.
List renders bullet-pointed or numbered lists with optional wrapping.
Example:
use cliux::{Tag, List};
fn main() {
Tag::new("beta").rounded().color("yellow").bold(true).print();
Tag::new("admin").curly().color("red").print();
Tag::new("draft").print();
List::new(vec!["First item", "Second item", "Third item"])
.bullet("*")
.width(40)
.print();
List::new(vec!["One", "Two", "Three"])
.numbered()
.print();
}
Output:
Suggestions for more components or features are welcome.
Schard
November 5, 2025, 12:48pm
5
The field numbered: bool in List is superfluous. You can determine whether it's a numbered or bullet list by determining whether bullet is None or not.
Pjdur
November 5, 2025, 5:55pm
6
Thanks for pointing that out. I refactored it before publishing v0.4.0, which is now the latest version.
Pjdur
November 5, 2025, 6:29pm
7
cliux v0.4.0 has been released, with two new components: Table and Note, and a small internal refactor to List.
Table renders structured rows and columns with optional headers, borders, and custom widths.
Note displays styled callouts for tips, warnings, and info blocks — with emoji, color, and border styles.
List has been internally cleaned up: it now infers numbering from bullet = None.
Example:
use cliux::{Table, Note};
fn main() {
Table::new()
.headers(&["Name", "Status"])
.row(&["cliux", "active"])
.row(&["other", "pending"])
.widths(&[20, 10])
.bordered(true)
.print();
Note::new("Be careful with this setting.")
.kind("warning")
.style("rounded")
.width(40)
.print();
Note::new("Tip: You can use --force here.")
.kind("info")
.style("+")
.width(40)
.print();
}
Output:
emoji rendering might be different across terminals, if alignment is off, try monospace-safe symbols like !, *, or i.
Suggestions for more components or features are welcome.
Schard
November 6, 2025, 6:35am
8
This is a nice little TUI library btw. And sorry for the nitpicking yesterday. I didn't read correctly and assumed this was a request for a code review.
1 Like
Pjdur
November 6, 2025, 4:25pm
9
Thanks for the compliment. Nice to know you found it interesting.
Pjdur
November 8, 2025, 12:48pm
10
cliux v0.5.0 has been released, with two new components Input and Confirm.
Examples:
Input:
use cliux::Input;
fn main() {
let name = Input::new("What's your name?")
.default("Anonymous")
.bold(true)
.color("cyan")
.style("rounded")
.width(40)
.prompt();
println!("Hello, {}!", name);
}
Confirm:
use cliux::Confirm;
fn main() {
let confirmed = Confirm::new("Delete file?")
.color("red")
.bold(true)
.style("square")
.width(40)
.default(false)
.prompt();
if confirmed {
println!("File deleted.");
} else {
println!("Operation cancelled.");
}
}
Output: