PHPackages                             sugarcraft/candy-mold - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sugarcraft/candy-mold

ActiveProject[Utility &amp; Helpers](/categories/utility)

sugarcraft/candy-mold
=====================

Skeleton repo for bootstrapping a SugarCraft TUI app — `composer create-project sugarcraft/candy-mold my-app`. Ships a runnable counter Model wired through Program, plus a docs-as-code walkthrough that maps every file to the concept it demonstrates.

10PHP

Since Jun 29Pushed 1mo agoCompare

[ Source](https://github.com/sugarcraft/candy-mold)[ Packagist](https://packagist.org/packages/sugarcraft/candy-mold)[ RSS](/packages/sugarcraft-candy-mold/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

[![candy-mold](.assets/icon.png)](.assets/icon.png)

CandyMold
=========

[](#candymold)

[![CI](https://github.com/detain/sugarcraft/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/detain/sugarcraft/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/c06f0e6047168edbd404c4c4276a72aea8d3e7dafb4b16a839ba1246e33ece57/68747470733a2f2f636f6465636f762e696f2f67682f64657461696e2f737567617263726166742f6272616e63682f6d61737465722f67726170682f62616467652e7376673f666c61673d63616e64792d6d6f6c64)](https://app.codecov.io/gh/detain/sugarcraft?flags%5B0%5D=candy-mold)[![Packagist Version](https://camo.githubusercontent.com/f236a0890ab5750a59ba136b7dc714b0a7f79323fc4a577342e7703b615b041e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f737567617263726166742f63616e64792d6d6f6c643f6c6162656c3d7061636b6167697374)](https://packagist.org/packages/sugarcraft/candy-mold)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP](https://camo.githubusercontent.com/e78ffc83837c0d12647811a7fd1910c3cbeae04988de94bb4fd5b67e0874696a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d254532253839254135382e312d3838393262662e737667)](https://www.php.net/)

[![demo](.vhs/start.gif)](.vhs/start.gif)

Skeleton repo for bootstrapping a SugarCraft TUI app. Pour your model into the mold and you've got a working app.

```
composer create-project sugarcraft/candy-mold my-app
cd my-app
./bin/start
```

and you'll see a working counter. Replace `src/Counter.php` with your own `Model`, keep editing.

What you get
------------

[](#what-you-get)

```
my-app/
├── composer.json     # requires candy-core + candy-sprinkles
├── phpunit.xml
├── bin/start         # entry point — runs Program(new Counter())
├── src/
│   └── Counter.php   # demo Model with up/down/quit, styled border
└── tests/
    └── CounterTest.php

```

`bin/start` is just three meaningful lines: load the autoloader, instantiate your `Model`, hand it to `Program::run()`. The Program harness owns the event loop, render tick, signal handling, raw-mode setup, and alt-screen lifecycle — you only write Models.

Anatomy of a SugarCraft Model
-----------------------------

[](#anatomy-of-a-sugarcraft-model)

A `Model` is three pure methods:

```
public function init(): ?\Closure;            // optional startup Cmd (timers, fetch...)
public function update(Msg $msg): array;       // [nextModel, ?Cmd]
public function view(): string;                // current frame
```

The shape is borrowed verbatim from Bubble Tea / The Elm Architecture. State lives on the value object, transitions are pure functions, side effects (timers, HTTP, file I/O) get *scheduled* as Cmds rather than executed inline.

`update()` always returns a new `Model` rather than mutating `$this`. That's why the demo declares `public readonly int $n` — the only way to "change" the count is to construct a fresh Counter with the new value.

Common next steps
-----------------

[](#common-next-steps)

Want to…Reach for…Add a text input`sugarcraft/sugar-bits` — `TextInput`Show a spinner while loading`sugarcraft/sugar-bits` — `Spinner`Render Markdown help text`sugarcraft/candy-shine` — `Renderer`Tail a log into a scrollable pane`sugarcraft/sugar-bits` — `Viewport`Build a multi-page wizard`sugarcraft/sugar-prompt` — `Group`Plot a sparkline`sugarcraft/sugar-charts` — `Sparkline`Make it `ssh`-accessible`sugarcraft/candy-wish`Add the dep, import its classes, return them from `view()`. They're all pure renderers on the same `Style`-based vocabulary.

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

The included `tests/CounterTest.php` shows how to test `update()` deterministically by constructing `Msg` objects directly. No event loop, no terminal, no mocking — just call methods and assert the returned tuple.

Panic Handler (Optional)
------------------------

[](#panic-handler-optional)

SugarCraft supports an opt-in panic handler that catches uncaught exceptions and displays a styled backtrace when the app crashes. To enable it, uncomment the panic handler block in `bin/start`:

```
// use SugarCraft\Log\Log;
// Log::installPanicHandler();
```

This feature requires `sugarcraft/candy-log` as a dependency.

License
-------

[](#license)

MIT.

###  Health Score

20

—

LowBetter than 12% of packages

Maintenance59

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 98.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/b1036e0717211b8030b83cbe729e8ba6ba442fdbd5285fb97a39d7dcfe339342?d=identicon)[detain](/maintainers/detain)

---

Top Contributors

[![detain](https://avatars.githubusercontent.com/u/1364504?v=4)](https://github.com/detain "detain (61 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

boilerplatebootstrapcandycorecomposer-create-projectcreate-projectexample-projectget-startedinstallmoldnew-packageonboardingproject-templatequickstartscaffoldingskeletonstartertemplatetuiwizard

### Embed Badge

![Health badge](/badges/sugarcraft-candy-mold/health.svg)

```
[![Health](https://phpackages.com/badges/sugarcraft-candy-mold/health.svg)](https://phpackages.com/packages/sugarcraft-candy-mold)
```

###  Alternatives

[bwoester/yii-static-events-component

Attach events on class base.

1011.0k3](/packages/bwoester-yii-static-events-component)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
