SugarCraft is a complete terminal-application stack for modern PHP: an MVC-style Model–Update–View runtime for terminal user interfaces (TUIs); styling, layout, and form engines; reusable components; charts; and terminal emulators and plumbing — plus a fleet of finished apps. Every package is composer-installable and requires PHP 8.3+; the interactive stack — runtime, components, and apps — runs async on a ReactPHP event loop.
🌐 Website: sugarcraft.github.io — library matrix, quickstart, comparison page. 📖 New here? Getting started — a finished binary, a first app, or a chart in five minutes. 📚 Vocabulary: Glossary — every term this README uses, defined with its source file.
composer require sugarcraft/sugarcraft # umbrella metapackage — every library
composer require sugarcraft/sugar-style # …or just the package you needEvery package installs independently with Composer. The libraries are grouped by layer:
| Library | Role | |
|---|---|---|
| SugarCraft | MVC-style Model–Update–View TUI runtime — Model / Msg / Cmd / Program, plus a frame-diff renderer with an opt-in cursed cell-diff mode. |
|
| SugarAnsiParser | ECMA-48 VT500 state machine — ANSI byte-stream parser with abstract Handler interface. Extraction from sugar-vterm. | |
| SugarCellBuffer | Cell-grid value objects — immutable Buffer (2-D cell grid) and Cell (rune/style/link/width). Shared foundation for all rendering; Buffer::diff() included. |
|
| SugarConstraints | Constraint-based layout solver — LayoutSolver interface with a deterministic GreedySolver engine (CassowarySolver kept only as a deprecated shim). |
|
| SugarAsync | Shared async vocabulary for ReactPHP — CancellationToken, Subscriptions, AsyncOps helpers (withTimeout, retry, debounce, throttle). | |
| SugarInput | Terminal input decoder — raw TTY bytes to typed events: keyboard (Kitty progressive protocol, xterm modifyOtherKeys, legacy encodings) and mouse (SGR, urxvt, X10) via InputDriver / EscapeDecoder. |
|
| SugarMouse | Mouse hit-testing — mark rendered regions, scan an event, get the zone back; ZoneClickTracker for press/release dedupe, plus the absorbed bubblezone-style Zones Manager (hover / drag / multi-click) under SugarCraft\Mouse\Zones. Owned per consumer or via Zones\Manager global. |
|
| SugarStyle | Declarative styling + layout — Style, Border, Table, List, Tree, Layout::join, Place, Canvas (multi-layer compositor). |
|
| SugarTesting | Test harness for SugarCraft apps — ProgramSimulator, golden-file assertions, snapshot helpers. | |
| SugarSpring | Damped spring physics + Newtonian projectile simulation. | |
| SugarFuzzy | Fuzzy string matching with scored match indices — powers filter-as-you-type highlighting across the ecosystem. | |
| SugarWidgets | Components: TextInput, TextArea, ItemList, Table, Tabs, Tree, Scrollbar, Viewport, FilePicker, Progress, Spinner, Cursor, Help, Key, Paginator, Stopwatch, Timer. | |
| SugarVterm | Virtual terminal emulator — ANSI byte stream → cell grid + cursor + mode state. | |
| SugarPty | Pseudo-terminal primitive — Pty::open() master/slave round-trip via FFI to libc; spawn/resize/non-blocking I/O. Linux + macOS only. |
|
| SugarForms | Form library (port of charmbracelet/huh) and shared form engine behind SugarWidgets — Note, Input, Confirm, Select, MultiSelect, Text, FilePicker, Date, Slider, Color, NumberField, RadioPills; multi-page Groups; stock themes; validators; fuzzy / async suggestions; ActionSpinner. | |
| SugarFocus | Focus-ring state machine — ordered focusable regions with Tab/Shift-Tab traversal. | |
| SugarGallery | Poster grids & rails for media TUIs — virtualized PosterGrid, Rail carousel, PosterCard. | |
| SugarCharts | Canvas + Sparkline, Bar, Line, Heatmap, Scatter, TimeSeries, Streamline, Waveline, OHLC, Picture (Sixel/Kitty/iTerm2). | |
| SugarImage | Image-to-cell renderer — PNG/JPEG/static GIF decoded via ext-gd, drawn with the best available protocol (Kitty, iTerm2, Sixel; an ANSI half-block fallback is always available). | |
| SugarMarkdown | Markdown → ANSI renderer with word-wrap, OSC 8 hyperlinks, 9 built-in themes. | |
| SugarCli | CLI presentation helpers — StatusLine, Banner, Section, Stage, HelpText. | |
| SugarSshServer | SSH server middleware — Logger, Auth, RateLimit, and the BubbleTea middleware that mounts a SugarCraft Program over ForceCommand (HostSshd transport). |
|
| SugarMetrics | Telemetry primitives — counters, gauges, histograms with InMemory / JSON / StatsD / Prometheus textfile / Multi backends, plus a SugarSshServer session middleware. | |
| SugarLog | Colorful leveled logger — Debug / Info / Warn / Error / Fatal with structured context, Text / JSON / Logfmt formatters, sub-loggers, and StandardLogAdapter. | |
| SugarColorprofile | Terminal color profile detection + ANSI / ANSI256 / TrueColor conversion. StandardColors and ProfileWriter. | |
| SugarTreelist | Tree/list view with box-drawing prefixes, cursor navigation, word-wrap, and filter-as-you-type. | |
| SugarPanels | Box-drawing layout engine — H/V panel composition with weighted sizing, borders, and nested grids. | |
| SugarOverlay | Terminal overlay compositor — composites Veil overlays with backdrop dimming, z-stack ordering, positioning, and click-outside hit-testing; opt-in Veil::withUntrustedContent() at the veil boundary. |
|
| SugarNavstack | Navigation breadcrumbs — mutable NavStack with explicit push/pop, width-aware breadcrumbs, and substring filter. | |
| SugarDashboard | Dashboard TUI library — column grid layout, framed panels, status bar, tabs, and more. | |
| SugarQuickpick | Fuzzy finder overlay — type to filter a list, arrow keys to select, Enter to confirm; wraps any Model. | |
| SugarFlexbox | FlexBox layout engine + simple sort/filter table. Ratio-based sizing, gap, align, per-column styling. | |
| SugarToast | Floating notification overlays — Info / Success / Warning / Error types, configurable position and auto-dismiss. | |
| SugarDatepicker | Interactive month-grid date picker — keyboard navigation, min/max date constraints, locale day names, ANSI rendering. | |
| SugarReadline | Interactive prompts — Text, Confirm, Selection, MultiSelect, Textarea. State-machine model, no external readline dependency. | |
| SugarTable | Full-featured interactive data table — column definitions, StyledCell ANSI formatting, pagination, frozen rows/cols. | |
| SugarDiff | Unified-diff engine — LCS line diff, diff -u hunks, writer + line-number scanner. Extracted from candy-code. |
|
| Sugar MCP Client | Model Context Protocol (MCP) client core — JSON-RPC 2.0 codec, stdio transport with bounded child lifecycle, initialize/tools handshake, tool narrowing. Extracted from candy-code. | |
| SugarAnimation | ANSI/GIF animation toolkit — ext-gd decode, cell-grid downsample, solid / luminance-ramp presets, .ansi art playback; the viewer CLI lives in candy-gifview. |
|
| SugarVideo | Terminal video player — pipes mp4 (and more) through ffmpeg/ffprobe on the fly and renders to ASCII / ANSI / truecolor half-block / sixel / kitty (GIF via ext-gd, no ffmpeg). |
Renamed packages (2026-10): every package moved to the two-prefix
scheme above — candy- for runnable apps and CLI tools, sugar- for
libraries (the honey- family was retired). The full old → new map, with
redirect notes, lives in
PROJECT_NAMES.md.
Each library has its own README.md with usage examples and a deep dive into
its public API.
Save as counter.php in a project with composer require sugarcraft/sugar-core,
then run php counter.php:
use SugarCraft\Core\{Cmd, KeyType, Model, Msg, Program, Subscriptions};
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->type === KeyType::Char && $msg->rune === 'q') {
return [$this, Cmd::quit()];
}
return [
$msg instanceof KeyMsg && $msg->type === KeyType::Up
? new self($this->n + 1)
: ($msg instanceof KeyMsg && $msg->type === KeyType::Down
? new self($this->n - 1)
: $this),
null,
];
}
public function view(): string { return "n = {$this->n}\n↑ ↓ to count, q to quit\n"; }
public function subscriptions(): ?Subscriptions { return null; }
}
(new Program(new Counter()))->run();- PHP 8.3+ — fibers, readonly props, enums,
match, intersection types. - Runtime: ReactPHP event loop — input, signals, render tick, and command execution all run concurrently on a single loop.
- Style: PSR-12 + readonly DTOs. Every
Style,Model, etc. is immutable —with*()returns a new instance. - Testing: PHPUnit 10. Snapshot ANSI tests for renderers; scripted-input event tests for the runtime.
- Layout: monorepo; every library also publishes as a standalone package and will later split into its own repo.
Every library in the table above ships at v1, each with its own composer
package and PHPUnit suite, and CI publishes per-library coverage to Codecov;
the rendering libraries pin their output with snapshot-ANSI tests. The
website library matrix carries live
per-package status, and each library's README.md documents its full public
API.
The full package roster lives in MATCHUPS.md, and the contributor / agent playbook in AGENTS.md walks through the complete integration checklist: naming conventions, package skeleton, tests, examples, VHS demos (terminal sessions recorded as GIFs), website tiles, and the central docs to update. AI assistants should read AGENTS.md first.
The umbrella package is a metapackage; each library has its own
composer.json + vendor/. To test everything:
for d in candy-* sugar-*; do
[ -f "$d/phpunit.xml" ] || continue
(cd "$d" && composer install --quiet && vendor/bin/phpunit) || exit 1
doneCode style is enforced via php-cs-fixer (root .php-cs-fixer.dist.php). Run from the repo root:
PHP_CS_FIXER_IGNORE_ENV=1 php-cs-fixer fix --diff --allow-risky=yesSee CONTRIBUTING.md. Bugs, feature requests, and new libraries — original tools, components, and terminal apps that fill gaps in the PHP stack — are all welcome. For security issues, see SECURITY.md. The fleet trust model — what counts as untrusted input and where the sanitize gates must sit — is docs/TRUST-BOUNDARY.md.
MIT.
SugarCraft is a PHP-native project. Its original design inspiration came from the Go terminal ecosystem — notably Bubble Tea and the wider Charm family of libraries — reimagined here for PHP 8.3+.


