- 9 built‑in styles (Single, Double, Round, Bold, SingleDouble, DoubleSingle, Classic, Hidden, Block)
- Custom glyphs for all corners and edges
- Title positions: Inside, Top, Bottom
- Content alignment: Left, Center, Right
- Optional content wrapping with
WrapContentandWrapLimit - Color support with:
- First 16 ANSI color names
#RGB,#RRGGBB,rgb:RRRR/GGGG/BBBB,rgba:RRRR/GGGG/BBBB/AAAA
- Unicode and emoji support with proper width handling
- Explicit errors from
Render, plusMustRenderfor panic‑on‑error
go get github.com/box-cli-maker/box-cli-maker/v3package main
import (
"fmt"
box "github.com/box-cli-maker/box-cli-maker/v3"
)
func main() {
b := box.NewBox().
Style(box.Single). // single-line border
Padding(2, 1). // inner padding: x (horizontal), y (vertical)
TitlePosition(box.Top).
ContentAlign(box.Center).
Color(box.Cyan).
TitleColor(box.BrightYellow)
out, err := b.Render("Box CLI Maker", "Render highly customizable boxes\n in the terminal")
if err != nil {
panic(err)
}
fmt.Println(out)
}NewBox constructs a box with the default Single style.
Configure it via fluent methods, then call Render (or MustRender) to get the box as a string.
b := box.NewBox() // recommendedYou can clone a configured box and tweak it:
base := box.NewBox().
Style(box.Single).
Padding(2, 1).
ContentAlign(box.Left)
info := base.Copy().Color(box.Green)
warn := base.Copy().Color(box.Yellow)Select a built‑in style:
b.Style(box.Double)You can override any glyph after choosing a style:
b.Style(box.Single).
TopLeft("+").
TopRight("+").
BottomLeft("+").
BottomRight("+").
Horizontal("-").
Vertical("|")Title position:
b.TitlePosition(box.Inside) // default
b.TitlePosition(box.Top)
b.TitlePosition(box.Bottom)Content alignment:
b.ContentAlign(box.Left) // default
b.ContentAlign(box.Center)
b.ContentAlign(box.Right)b.Padding(px, py) // horizontal (px) and vertical (py) padding
b.HPadding(px) // horizontal only
b.VPadding(py) // vertical onlyNegative padding values are allowed to be set but cause Render to return an error.
b.WrapContent(true) // enable wrapping (default width: 2/3 of terminal)
b.WrapLimit(40) // set explicit wrap width (enables wrapping)
b.WrapContent(false) // disable wrappingRender returns an error if the wrap limit is negative or the terminal width cannot be determined when wrapping is enabled without a limit.
Colors can be applied to:
- Title:
TitleColor - Content:
ContentColor - Border:
Color
Accepted formats:
-
First 16 ANSI names:
box.Black, box.Red, box.Green, box.Yellow, box.Blue, box.Magenta, box.Cyan, box.Whiteand their bright variants:box.BrightBlack, box.BrightRed, box.BrightGreen, box.BrightYellow, box.BrightBlue, box.BrightMagenta, box.BrightCyan, box.BrightWhite
(plus a few aliases likebox.HiRed,box.HiBlue, etc.) -
Hex and XParseColor formats (Supports TrueColor and 8-bit):
#RGB#RRGGBBrgb:RRRR/GGGG/BBBBrgba:RRRR/GGGG/BBBB/AAAA
Example:
b.TitleColor(box.BrightYellow)
b.ContentColor("#00FF00")
b.Color("rgb:0000/ffff/0000")Invalid colors cause Render to return an error.
out, err := b.Render("Title", "Content")
if err != nil {
// handle invalid style, colors, padding, wrapping, etc.
}
fmt.Println(out)Render returns an error if:
- The
BoxStyleis invalid - The
TitlePositionis invalid - The wrap limit is negative
- Padding is negative
- A multiline title is used with a non‑
Insidetitle position - Any configured colors are invalid
- Terminal width detection fails when needed for wrapping
For convenience:
out := b.MustRender("Title", "Content") // panics on errorThe examples directory contains small, focused programs that showcase different features:
simple_box– minimal single box with title and content.content_align– compareLeft,Center, andRightcontent alignment.content_wrap– demonstrateWrapContent/WrapLimitwith long text.title_positions– showInside,Top, andBottomtitle placement.box_styles– render all built‑in border styles and colors.custom_box– build boxes using fully custom corner/edge glyphs.ansi_styles_and_links– use bold/underline/blink/strikethrough and OSC 8 hyperlinks.colors_and_unicode– mix hex/ANSI colors with CJK, emoji, and wrapping.ansi_art– render more decorative/"artistic" boxes.shared_styles– derive multiple boxes from a shared base style withCopy.ksctl– real‑world example from ksctl showing wide titles vs narrow content.lolcat– rainbow color demo using custom ANSI styling helpers.readme– code used to generate the screenshot at the top of this README.
This library uses mattn/go-runewidth and github.com/charmbracelet/x/ansi to handle:
- Wide characters (e.g., CJK)
- Emojis and other multi‑cell glyphs
- Stripping ANSI sequences when measuring widths
Note:
- Rendering quality depends on the terminal emulator and font. Some combinations may misalign visually.
- Indic scripts and complex text may not display correctly in most terminals.
- Online playgrounds and many CI environments often use basic fonts and may not render Unicode/emoji correctly; widths might be misreported.
v3 is a new major version with a redesigned API.
Key changes:
-
Configstruct andNew(Config)have been replaced with:b := box.NewBox(). Style(box.Single). Padding(2, 1). TitlePosition(box.Top). ContentAlign(box.Left)
-
String‑based fields (
Type,ContentAlign,TitlePos) are now strongly typed:"Single"→box.Single"Top"→box.Top"Center"→box.Center
-
Colors:
- No more
interface{}colors (uint,[3]uint, etc.). - Use ANSI names or the documented hex/rgb formats instead.
- Invalid colors now error at
Rendertime.
- No more
-
Print/Printlnbehavior can be replicated byfmt.Println(b.MustRender(...))or your own helper.
Read more at Migration guide.
The old v2 API remains available at:
go get github.com/Delta456/box-cli-maker/v2but is no longer actively developed.
kubernetes/minikube: Run Kubernetes locally.- And others listed on pkg.go.dev.
Thanks to:
for inspiration, and to all contributors who have improved this library over time.
Licensed under MIT.













