A Rust TUI for generating laser-cut box outlines — in the spirit of florianfesti/boxes, but with a live terminal preview, cut-path optimization, and first-class support for Kitty, classic terminals, and browser-based "web TUIs".
Output formats: SVG and DXF (R12), exportable to disk or straight to the system clipboard.
| Design | Description |
|---|---|
| Closed Box | 6 panels, finger-jointed on all mating edges |
| Open Tray | 5 panels, flat wall tops |
| Divided Tray | Tray plus internal dividers with friction-fit bottom tabs into floor slots |
| Hinged Box | Tray with a one-piece wrap-around lid using a living hinge (staggered relief cuts), thumb scallop, and engraved fold guides |
Optional hex ventilation pattern (v key) can be punched into the base panel.
- Shared-edge deduplication — set Part spacing to
0and panels of equal width are mirror-butted so mating outlines collapse into a single cut line. On the default closed box this drops total cut length from ~1840 mm to ~1646 mm and removes two full panel edges of burn/char. - Segment dedup + re-chaining — coincident segments anywhere on the sheet are cut once; remaining segments are re-chained into the longest possible polylines, minimizing pierce points (each pierce costs time and scorch).
- Collinear merge — consecutive collinear vertices are removed for smaller, cleaner files.
- Travel ordering — inner cuts (slots, vents, hinge) are ordered before outlines, then greedily nearest-neighbor sorted to reduce head travel.
- Kerf compensation done in the joint generator itself: finger flanks are shifted by ±kerf/2 so fingers come out wider and gaps narrower — joints fit snugly straight off the machine.
boxes.rs probes the environment at startup and picks the richest tier:
| Tier | Detected via | Preview | Clipboard |
|---|---|---|---|
| Kitty | TERM=*kitty*, KITTY_WINDOW_ID |
Braille canvas plus hi-res raster preview via the Kitty graphics protocol (p key) |
OSC 52 + system tools |
| Modern | xterm-256color, tmux, WezTerm, Alacritty, ttyd/xterm.js web TUIs | Braille canvas | OSC 52 + system tools |
| Basic | anything else | ASCII-safe UI | OSC 52 |
webtui: running under ttyd,
GoTTY, or any xterm.js front-end works out of the box — the Modern tier's
braille preview renders fine in browsers, and clipboard copy uses OSC 52,
which xterm.js forwards to the browser clipboard. So c (copy SVG) works even
when boxes.rs runs on a remote box viewed through a browser tab.
Clipboard strategy: try wl-copy, then xclip, then fall back to OSC 52
(which also traverses SSH and tmux).
cargo build --release
# binary at target/release/boxes.rsMSRV: Rust 1.75 (dependency versions are pinned in Cargo.toml accordingly).
./target/release/boxes.rs # interactive TUI
./target/release/boxes.rs --export both --out mybox # headless export
./target/release/boxes.rs --help| Key | Action |
|---|---|
↑/↓ or j/k |
select parameter |
←/→ or h/l |
adjust value (Shift = ×10) |
Enter |
type a value directly |
d |
cycle design |
m |
cycle material preset |
v |
toggle hex ventilation |
p |
toggle Kitty hi-res preview |
s / x |
save SVG / DXF to disk |
c |
copy SVG to clipboard |
q |
quit |
Config is looked up in $BOXES_RS_CONFIG_DIR, then ./config, then
~/.config/boxes.rs.
materials.toml — material presets:
[[material]]
name = "Plywood 3mm"
thickness = 3.0 # mm
kerf = 0.15 # mm — calibrate for YOUR machine (see below)defaults.toml — startup parameters:
design = "closed_box" # closed_box | open_tray | divided_tray | hinged_box
width = 120.0 # outer dimensions, mm
depth = 80.0
height = 50.0
finger_width = 12.0
material = "Plywood 3mm"
dividers = 2
hinge_columns = 14
spacing = 0.0 # 0 enables shared-edge cut deduplication
output_dir = "."
file_stem = "boxes.rs"- SVG: millimeter units, red
#ff00000.1 mm strokes for cuts, blue#0000fffor engraves — the convention most laser software (LightBurn, Glowforge, Epilog drivers) recognizes directly. - DXF: ASCII R12 (AC1009) with
CUTandENGRAVElayers,$INSUNITSset to millimeters. Validated against ezdxf.
- Kerf calibration: cut a 20 mm test square, measure it, and set
kerf = 20.0 - measured. Kerf varies with material, power, and speed. - Dividers are friction-fit; if they're loose, bump kerf up by ~0.05 mm.
- Living hinge: bend gently a few times before final assembly; thinner material (≤3 mm) bends best. Increase Hinge columns for a tighter radius.
