A Rust crate for creating styled, multi-segment text boxes in the terminal.
Dual-licensed under Apache 2.0 or MIT.
-
9 border styles — classic ASCII, single, double, bold, rounded, bold-corners, and more
-
True-color support — hex color codes (
#rrggbb) for borders and per-line text -
Multi-segment boxes — stack sections separated by horizontal dividers
-
Columnar layouts — side-by-side columns inside a single box, with configurable width ratios and correct junction characters (
┼/┬/┴) where column boundaries meet across adjacent segments -
Automatic word wrapping — wraps to terminal width, respecting internal padding
-
Text alignment — left, center, or right per segment
-
Terminal-aware sizing — auto-sizes to terminal width, or set a fixed width
-
Two APIs — imperative
Boxystruct and fluentBoxyBuilder -
Full Unicode support — grapheme-cluster-aware word wrapping and display-width-correct alignment for CJK, emoji, and combining marks.
Note: ZWJ sequences (e.g. 👨👩👧) may display with slightly incorrect padding on some terminals due to disagreements between the Unicode standard and individual terminal emulators on ZWJ rendering width; plain emoji (🦀, 🚀) and CJK text are unaffected
-
Macro support —
boxy!for quick one-liners — still a work in progress with limited functionality
[dependencies]
boxy-cli = "2.1.0"Or:
cargo add boxy-cliuse boxy_cli::prelude::*;
Boxy::builder()
.box_type(BoxType::Double)
.color("#00ffff")
.add_segment("Hello, boxy-cli!", "#ffffff", BoxAlign::Center)
.add_segment("A terminal box library for Rust.", "#32CD32", BoxAlign::Left)
.add_line("Second line in the same segment.", "#aaaaaa")
.padding(BoxPad::uniform(1), BoxPad::vh(1, 2))
.build()
.display();use boxy_cli::prelude::*;
let mut b = Boxy::new(BoxType::Bold, "#00ffff");
b.add_text_sgmt("Hello, boxy-cli!", "#ffffff", BoxAlign::Center);
b.add_text_sgmt("A terminal box library for Rust.", "#32CD32", BoxAlign::Left);
b.add_text_line("Second line in the same segment.", "#aaaaaa");
b.display();use boxy_cli::prelude::*;
let mut b = boxy!(type: BoxType::Double, color: "#00ffff", internal_pad: 1, alignment: BoxAlign::Left);
b.add_text_sgmt("Hello from the macro!", "#ffffff", BoxAlign::Center);
b.display();Columnar segments let you place content side-by-side inside one box. Column widths are
controlled by ratio values — vec![1, 2, 1] gives the middle column twice the space of the
others.
Where column boundaries from adjacent segments coincide, boxy-cli renders the correct
junction character automatically:
┌─────────────────┬─────────────────┬─────────────┐
│ Project | Status │ Purpose |
├─────────────────┼─────────────────┴─────────────┤ <- ┼ where both have a boundary
│ Lumio V2 │ Shipped Internship │ ┴ where only the top segment does
└─────────────────┴───────────────────────────────┘
use boxy_cli::prelude::*;
let mut b = Boxy::new(BoxType::Single, "#00ffff");
// Plain text header segment
b.add_text_sgmt("Project Status", "#ffffff", BoxAlign::Center);
// 3-column segment with equal widths
b.add_col_text_sgmt(BoxAlign::Left, 3);
b.add_col_text_line("Name", "#aaaaaa", &0usize);
b.add_col_text_line("Status", "#aaaaaa", &1usize);
b.add_col_text_line("Notes", "#aaaaaa", &2usize);
b.add_col_text_line("Lumio V2", "#ffffff", &0usize);
b.add_col_text_line("Shipped", "#32CD32", &1usize);
b.add_col_text_line("Internship project", "#ffffff", &2usize);
// Optional: customize column width ratios (must match column count)
b.set_segment_ratios(1, vec![1, 1, 2]);
b.display();Or using the builder:
use boxy_cli::prelude::*;
Boxy::builder()
.add_segment("Project Status", "#ffffff", BoxAlign::Center)
.add_col_segment(BoxAlign::Left, 3)
.add_col_line("Name", "#aaaaaa", 0)
.add_col_line("Status", "#aaaaaa", 1)
.add_col_line("Notes", "#aaaaaa", 2)
.add_col_line("Lumio V2", "#ffffff", 0)
.add_col_line("Shipped", "#32CD32", 1)
.add_col_line("Internship project", "#ffffff", 2)
.segment_ratios(1, vec![1, 1, 2])
.build()
.display();BoxType variant |
Appearance |
|---|---|
Single |
┌─┐ / │ / └─┘ |
Double |
╔═╗ / ║ / ╚═╝ |
Bold |
┏━┓ / ┃ / ┗━┛ |
Rounded |
╭─╮ / │ / ╰─╯ |
DoubleHorizontal |
╒═╕ / │ / ╘═╛ |
DoubleVertical |
╓─╖ / ║ / ╙─╜ |
BoldCorners |
┍━┑ / │ / ┕━┙ |
Classic |
+-+ / | / +-+ |
Empty |
invisible borders |
BoxPad controls spacing between the terminal edge and the box (external), and between the
box border and its text (internal).
use boxy_cli::prelude::*;
// Uniform padding on all sides
let pad = BoxPad::uniform(2);
// Separate vertical and horizontal values
let pad = BoxPad::vh(1, 3); // top/bottom: 1, left/right: 3
// Full control: top, left, down, right
let pad = BoxPad::from_tldr(1, 2, 1, 2);
let mut b = Boxy::new(BoxType::Single, "#00ffff");
b.set_ext_padding(BoxPad::uniform(1));
b.set_int_padding(BoxPad::vh(1, 2));
b.add_text_sgmt("Padded box", "#ffffff", BoxAlign::Center);
b.display();use boxy_cli::prelude::*;
fn main() {
let mut b = Boxy::new(BoxType::Bold, "#00ffff");
b.add_text_sgmt(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"#ffffff",
BoxAlign::Left,
);
b.add_text_sgmt(
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium \
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore \
veritatis et quasi architecto beatae vitae dicta sunt explicabo.",
"#ffffff",
BoxAlign::Left,
);
b.add_text_sgmt("Hello There", "#ffffff", BoxAlign::Center);
b.display();
}| Method | Description |
|---|---|
Boxy::new(type, color) |
Create a new box |
Boxy::builder() |
Start a builder chain |
add_text_sgmt(text, color, align) |
Add a plain text segment |
add_text_line(text, color) |
Add a line to the last segment |
add_text_line_indx(text, color, idx) |
Add a line to a specific segment |
add_col_text_sgmt(align, count) |
Add a columnar segment |
add_col_text_line(text, color, col) |
Add a line to a column in the last segment |
add_col_text_line_indx(text, color, seg, col) |
Add a line to a specific column in a specific segment |
set_segment_ratios(seg, ratios) |
Set column width ratios for a columnar segment |
set_align(align) |
Set box alignment within the terminal |
set_int_padding(pad) |
Set internal padding |
set_ext_padding(pad) |
Set external padding |
set_width(n) |
Fix the box width |
set_type(type) |
Change border style |
set_color(color) |
Change border color |
display() |
Render and print the box |
render(width) |
Render the box into a Vec<String> without printing |
For the full API reference see docs.rs/boxy-cli.



