SugarCraft — sweet to build, fun to use

Terminal UIs that taste like candy.

SugarCraft is the PHP port of the Charmbracelet TUI ecosystem — thirty-three libraries and twenty-three apps (fifty-six packages total). Elm-architecture runtime, declarative styling, animation, charts, forms, SSH-served apps, telemetry, file managers, an AI chat shell. Composer-installable, PHP 8.1+, fibers, async on ReactPHP.

33libraries
23apps
281VHS demos
PHP 8.1+fibers / ReactPHP
MITlicensed

The whole Charm stack — in PHP.

Click an icon to jump to its detail page. Every package is published independently, ships its own examples and PHPUnit suite, and shares a single styling vocabulary so they compose without glue code.

Built for the things Symfony Console can't do.

Persistent render loops, mouse + keyboard, alt-screen, async work without blocking the UI, multi-tenant SSH-served TUIs, charts and sparklines, animated spinners, multi-page forms, Markdown rendered straight to ANSI. The boring parts of CLI tooling — argv parsing, exit codes — pair perfectly with whatever Console framework you already use.

Thirty-three libraries, one ecosystem.

Each library has its own composer package, README, examples, and PHPUnit suite. Pull just the ones you need — or grab the umbrella metapackage and get the lot.

SugarCraft

GitHub →

Elm-architecture runtime — Model / Msg / Cmd / Program. Cursed cell-diff renderer for SSH bandwidth.

CandySprinkles

GitHub →

Declarative styling + layout. Style, Border, Table, List, Tree, Layout::join/Place, multi-layer Canvas.

CandyBuffer

GitHub →

Cell-grid value objects — immutable Buffer (2-D cell grid) and Cell (rune/style/link/width). Shared foundation for all rendering; Buffer::diff() ships in step-26.

CandyAsync

GitHub →

Shared async vocabulary — CancellationToken, Subscriptions, AsyncOps helpers (withTimeout, retry, debounce, throttle). Foundation for ReactPHP usage across the ecosystem.

HoneyBounce

GitHub →

Damped spring physics + Newtonian projectile sim. The animation engine behind every smooth scroll in the stack.

CandyZone

GitHub →

Mouse-zone tracker. Wrap rendered chunks, get back bounding boxes — clickable regions without coordinate math.

SugarBits

GitHub →

Fifteen components: TextInput, TextArea (dynamic-height), ItemList, Table (per-cell styleFunc), Tree, Viewport, FilePicker, Progress, Spinner, Cursor, Help, Key, Paginator, Stopwatch, Timer.

SugarCharts

GitHub →

Sparkline, Bar, Line, Heatmap, Scatter, TimeSeries, Streamline, Waveline, OHLC, plus Sixel / Kitty / iTerm2 image rendering.

SugarPrompt

GitHub →

Form library — Note, Input, Confirm, Select, MultiSelect, Text, FilePicker, multi-page Groups, six themes. Form-level KeyMap override per binding.

CandyShine

GitHub →

Markdown → ANSI renderer. Word-wrap, OSC 8 hyperlinks, syntax highlighting, eight themes, custom themes via JSON.

CandyKit

GitHub →

CLI presentation helpers — StatusLine, Banner, Section, Stage, HelpText. Library-only, no Symfony Console requirement.

CandyWish

GitHub →

SSH server middleware framework. Logger, Auth, RateLimit, BubbleTea — leans on OpenSSH ForceCommand for the wire protocol.

CandyMetrics

GitHub →

Telemetry primitives. Counter / Gauge / Histogram, four backends (InMemory, JSON, StatsD, Prometheus textfile), CandyWish session middleware.

CandyLog

GitHub →

Colorful leveled logger. Debug / Info / Warn / Error / Fatal with structured context, Text / JSON / Logfmt formatters, and sub-loggers.

CandyMosaic

GitHub →

Image-to-cell renderer — Sixel, Kitty, iTerm2, Unicode half-block; Picker facade; ext-gd.

CandyMouse

GitHub →

Self-contained Mark/Scan/Get mouse hit-testing (bubblezone pattern) + ZoneClickTracker for press/release deduplication. No external Manager wiring needed.

CandyPalette

GitHub →

Terminal color profile detection + ANSI / ANSI256 / TrueColor conversion. StandardColors and ProfileWriter.

CandyVt

GitHub →

In-memory virtual terminal emulator. ANSI byte stream → cell grid + cursor + mode state.

CandyVcr

GitHub →

Record + replay candy-core sessions — JSONL/YAML cassettes, Recorder hook, Player + Byte/Screen assertions, CLI.

CandyPty

GitHub →

PTY primitive for Linux + macOS — open / spawn / read / write / resize / size / setBlocking, Child lifecycle, SignalForwarder (SIGWINCH → resize).

CandyForms

GitHub →

Foundation lib for form primitives — TextInput, TextArea, ItemList, Viewport, FilePicker, Field interface, Confirm, Form.

CandyLister

GitHub →

Tree/list view with box-drawing prefixes, cursor navigation, word-wrap, and filter-as-you-type.

CandyLayout

GitHub →

Constraint-based layout solver — Cassowary simplex + greedy 5-phase fallback. LayoutSolver interface; swap solvers without touching call-sites.

SugarBoxer

GitHub →

Box-drawing layout engine. H/V panel composition with weighted sizing, borders, and nested grids.

SugarVeil

GitHub →

Terminal overlay compositor. Push/pop overlay views with z-ordering, positioning, and per-overlay teardown.

SugarCrumbs

GitHub →

Navigation breadcrumbs. Immutable NavStack with push/pop, shell-change detection, and type-ahead filter.

SugarDash

GitHub →

Dashboard TUI library — column grid layout, framed panels, status bar, tabs, and more.

CandyHermit

GitHub →

Fuzzy finder overlay. Type to filter a list, arrow keys to select, Enter to confirm. Bubbletea Model wrapper.

CandyInput

GitHub →

Terminal escape sequence decoder — legacy keys, Kitty keyboard, SGR 1006 mouse, focus, bracketed paste. The missing input layer for PHP TUI.

CandyFuzzy

GitHub →

Fuzzy string matching with scored matched indices — Smith-Waterman + Sahilm algorithms. Extracted from candy-forms; unblocks filter-highlighting UI.

SugarStickers

GitHub →

FlexBox layout engine + simple sort/filter table. Ratio-based sizing, gap, justify, align, per-column styling.

SugarToast

GitHub →

Floating notification overlays. Info / Success / Warning / Error types, configurable position and auto-dismiss.

SugarCalendar

GitHub →

Interactive month-grid date picker. Keyboard navigation, min/max date constraints, locale day names, ANSI rendering.

SugarReadline

GitHub →

Interactive prompts — Text, Confirm, Selection, MultiSelect, Textarea. State-machine model, no external readline dependency.

SugarTable

GitHub →

Full-featured interactive data table — port of Evertras/bubble-table. Column definitions, StyledCell ANSI formatting, pagination, frozen rows/cols.

CandyTesting

GitHub →

Test harness for TEA programs — ProgramSimulator, golden-file assertions, snapshot helpers. Pioneering what bubble-tea issue #1654 never shipped.

Twenty-three apps built on the stack.

Standalone executables — CLI tools (gum, glow, freeze…), full TUIs (file manager, git, SQLite, AI chat, games), and a project starter. Install via Composer, run as a CLI binary. Each has a detail page below with controls, architecture, and demo recordings.

CandyMold

GitHub →

composer create-project sugarcraft/candy-mold my-app — pour your model into the mold and you've got a working app.

CandyShell

GitHub →

Composer-installable CLI of thirteen subcommands — choose, confirm, file, filter, format, input, join, log, pager, spin, style, table, write.

CandyFreeze

GitHub →

Code → SVG screenshot. Traffic-light window controls, drop shadow, gutter line numbers, ANSI SGR parsing. No GD / Imagick.

SugarGlow

GitHub →

Markdown CLI viewer. Renders to stdout or opens a fullscreen pager. Eight themes, custom JSON themes, OSC 8 toggle.

SugarSpark

GitHub →

ANSI escape-sequence inspector. Labels SGR / CSI / OSC / DCS / APC / SS3 — feed it stdin, get a human-readable annotation back.

SugarWishlist

GitHub →

SSH endpoint launcher. YAML / JSON directory of `ssh user@host` shortcuts, interactive picker, pcntl_exec into the chosen ssh.

SugarSkate

GitHub →

In-memory key/value store with plugin backends. Memory, SQLite, Badger. Glob listing, TTL, batch operations.

SugarPost

GitHub →

Email sending library. SMTP + Resend API transports, attachments, HTML + plain-text multipart, fluent interface.

CandyServe

GitHub →

Self-hostable Git server over SSH (authorized keys), Git daemon, and HTTP. Users, repos, access control, optional LFS.

CandyTetris

GitHub →

Tetris clone — SRS rules, 7-bag RNG, ghost piece, NES scoring, level-driven gravity. 41 tests / 1535 assertions.

CandyFiles

GitHub →

Dual-pane file manager. Tab-swap focus, multi-select, sort cycling, hidden-file toggle, delete-with-confirm.

SugarCrush

GitHub →

AI coding-assistant chat shell. Pluggable Backend interface — wire to Anthropic / OpenAI / Ollama via a wrapper script.

CandyCrush

GitHub →

TUI AI coding assistant — multi-provider, multi-agent, skill-aware.

SugarStash

GitHub →

Three-pane git TUI — status / branches / log, single-key stage / unstage. Shells out to git for every mutation so your hooks + signing config keep working.

CandyQuery

GitHub →

SQLite browser TUI — list tables, peek at row data, run ad-hoc queries, explore query plans, and monitor server health. Multi-driver: SQLite, MySQL, and PostgreSQL.

SugarTick

GitHub →

Privacy-first coding-time tracker — JSONL on disk, SugarCharts-driven dashboard. No cloud, no MongoDB, bring-your-own-storage stays local.

CandyMines

GitHub →

Minesweeper — customisable board, recursive flood-fill, win/lose detection. Pure-state Board; first-click safety; deterministic-RNG injectable for tests.

CandyFlip

GitHub →

ASCII GIF viewer — ext-gd decode, downsample to a cell grid, render as ANSI 24-bit blocks or a luminance-ramp ASCII rendering.

SugarReel

GitHub →

Terminal video player — decodes mp4 (and more) on the fly and renders to ASCII / ANSI / truecolor half-block / sixel / kitty. Prior art: tplay, glyph, video-to-ascii.

HoneyFlap

GitHub →

Flappy-Bird in your terminal — bird motion is a HoneyBounce projectile, pipes scroll left at a fixed cell rate, collision is per-cell. PRNG-injectable for deterministic tests.

Five layers, no surprises.

SugarCraft is the same layered architecture as the Charm stack, translated package-by-package. The deps map cleanly so you can grab as much or as little as you need.

1. Foundation
SugarCraft::Util — Ansi, Color, ColorProfile, Width, Tty. Depended on by everything below.
2. Render + physics
CandySprinkles (lipgloss), HoneyBounce (harmonica). Pure rendering / pure math — no I/O.
3. Runtime
SugarCraft (bubbletea) — Model / Msg / Cmd / Program. Hooks Phase 1 + 2 onto a ReactPHP loop.
4. Components
SugarBits (bubbles), SugarCharts (ntcharts), SugarPrompt (huh), CandyZone (bubblezone). Composable widgets that drop into your Model.
5. Tooling libs + apps
Tooling libs: CandyShine (glamour), CandyKit (fang), CandyWish (wish), CandyMetrics (promwish), CandyLog (log), CandyPalette (colorprofile).
CLI apps: CandyShell (gum), SugarGlow (glow), SugarSpark (sequin), CandyFreeze (freeze), SugarWishlist (wishlist), CandyServe (soft-serve), SugarSkate (skate), SugarPost (pop).
TUI apps: CandyMold, CandyTetris, CandyFiles, SugarCrush, SugarStash, CandyQuery, SugarTick, CandyMines, CandyFlip, HoneyFlap.

Async-first

ReactPHP event loop under the hood. Cmds run as fibers; the render thread never blocks on I/O.

📐

Immutable values

Every Model, Style, Border, Theme is a readonly DTO. with*() returns a new instance — no hidden mutations.

🧪

Testable by design

Pure update functions and snapshot ANSI tests. No tmp dirs, no mocks for the renderer — just assert against the frame.

🎨

One styling vocabulary

Every package speaks Sprinkles\Style. Mix CandyShine output into a SugarBits Viewport, wrap that with a CandySprinkles Border — they all compose.

🔐

SSH the easy way

CandyWish leans on ForceCommand. sshd handles auth, ciphers, fail2ban, audit logs — you get a clean middleware programming model.

📦

No native extensions

Pure-PHP base flow. ext-pcntl, ext-gd, ext-ssh2 are optional for niche features.

See them run.

VHS-recorded GIFs of every interactive demo, regenerated on every push that touches the corresponding source. Two-hundred-eighty-one demos in total — these are the headliners; click into any library page for its full set.

From composer require to a working counter in ten lines.

Install the umbrella, drop the snippet below into a file, php counter.php. ↑ ↓ to count, q to quit.

1. Install

composer require sugarcraft/sugarcraft

2. Write the model

use SugarCraft\Core\{Cmd, KeyType, Model, Msg, Program};
use SugarCraft\Core\Msg\KeyMsg;

final class Counter implements Model {
    public function __construct(public readonly int $n = 0) {}
    public function init(): ?\Closure { return null; }

    public function update(Msg $msg): array {
        if ($msg instanceof KeyMsg && $msg->rune === 'q') return [$this, Cmd::quit()];
        return [match (true) {
            $msg instanceof KeyMsg && $msg->type === KeyType::Up   => new self($this->n + 1),
            $msg instanceof KeyMsg && $msg->type === KeyType::Down => new self($this->n - 1),
            default => $this,
        }, null];
    }

    public function view(): string { return "n = {$this->n}\n↑ ↓ to count, q to quit\n"; }
}

(new Program(new Counter()))->run();

3. Run it

php counter.php

Want a project skeleton instead?

composer create-project sugarcraft/candy-mold my-app scaffolds a runnable counter app with PHPUnit wired up — see CandyMold.

Why pick SugarCraft?

Three flavours of "build a TUI in PHP" — pick the row that matches your project's needs. (Full reasoning on the comparison page.)

Capability SugarCraft Symfony Console readline / raw
Elm-architecture runtime (Model / Msg / Cmd)
Async event loop (fibers + ReactPHP) partial
Declarative styling (CSS-like flexbox / borders) manual
Composable form library ✓ (SugarPrompt)
Mouse + key bindings
SSH-served apps (multi-tenant) ✓ (CandyWish)
Charts / sparklines / heatmaps ✓ (SugarCharts)
One-shot CLI prompts (gum-style) ✓ (CandyShell) primitive
Markdown → ANSI rendering ✓ (CandyShine)
Code → SVG screenshots ✓ (CandyFreeze)
Telemetry primitives (StatsD / Prom) ✓ (CandyMetrics)