Box CLI Maker
June 6, 2026 · View on GitHub
Features
- 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
- Title and 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
Installation
go get github.com/box-cli-maker/box-cli-maker/v3
Quick Start
package 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)
Margin(3, 5). // outer margin: 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.
API Overview
Construction
b := box.NewBox() // recommended
You 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)
Styles
Select a built‑in style:
b.Style(box.Double)
Styles showcase
box.Single
box.SingleDouble
box.Double
box.DoubleSingle
box.Bold
box.Round
box.Hidden
box.Classic
box.Block
You can override any glyph after choosing a style:
b.Style(box.Single).
TopLeft("+").
TopRight("+").
BottomLeft("+").
BottomRight("+").
Horizontal("-").
Vertical("|")
Titles and Alignment
Title position:
b.TitlePosition(box.Inside) // default
b.TitlePosition(box.Top)
b.TitlePosition(box.Bottom)
Title Position showcase
box.Inside
box.Top
box.Bottom
Title alignment:
b.TitleAlign(box.Left) // default for box.Top/box.Bottom Title Position
b.TitleAlign(box.Center) // default for box.Inside Title Position
b.TitleAlign(box.Right)
Title Alignment showcase
box.Left
box.Inside
![]()
box.Top
![]()
box.Bottom
![]()
box.Center
box.Inside
![]()
box.Top
![]()
box.Bottom
![]()
box.Right
box.Inside
![]()
box.Top
![]()
box.Bottom
![]()
Content alignment:
b.ContentAlign(box.Left) // default
b.ContentAlign(box.Center)
b.ContentAlign(box.Right)
Content Alignment showcase
box.Left
box.Center
box.Right
Padding
b.Padding(px, py) // horizontal (px) and vertical (py) padding
b.HPadding(px) // horizontal only
b.VPadding(py) // vertical only
Setting negative padding causes Render to return an error.
Margin
Margin adds space outside the box borders — horizontal margin prepends spaces to every line, vertical margin adds blank lines above and below.
b.Margin(mx, my) // horizontal (mx) and vertical (my) margin
b.HMargin(mx) // horizontal only
b.VMargin(my) // vertical only
Setting negative margin causes Render to return an error.
Wrapping
b.WrapContent(true) // enable wrapping (default: 2/3 of terminal width, minus any HMargin)
b.WrapLimit(40) // set explicit wrap width (enables wrapping)
b.WrapContent(false) // disable wrapping
Render returns an error if the wrap limit is negative or the terminal width cannot be determined when wrapping is enabled without a limit.
Colors
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.
Rendering
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
TitleAlignorContentAlignis invalid - The wrap limit is negative
- Padding is negative
- Margin 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 error
Examples
The 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.title_alignments– compareLeft,Center, andRighttitle alignment.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.
Unicode, Emoji, and Width Handling
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.
Migration from v2
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/v2
but is no longer actively developed.
Projects Using Box CLI Maker
kubernetes/minikube: Run Kubernetes locally.- And others listed on pkg.go.dev.
Acknowledgements
Thanks to:
for inspiration, and to all contributors who have improved this library over time.
License
Licensed under MIT.