Tiny, easy-to-remember ANSI escape helper for building terminal UIs in PHP. Chainable API for styles/colors/cursor control, with a few handy components (Table, Banner, Progressbar etc.) and utilities.
Works any terminal that supports ANSI escapes (most modern terminals on macOS/Linux and Windows Terminal/ConEmu on Windows 10+).
Let's keep simple things simple. 😌
You don't need a whole framework to build a simple CLI app.
- Colors: Foreground and background colors - standard 8/16 colors, 256-color, and truecolor (RGB, 24-bit)
- Text styles: bold, dim, italic, underline, inverse, hidden, strike-through
- Cursor control: movement, save/restore, show/hide, alternate screen buffer
- Components: Table, Banner, Progressbar, Spinner
- Writers: swap output target (stdout or in-memory for tests)
- Helpers: ANSI‑aware string length, simple input (line/multiline/confirm)
- PSR‑12, strict types, DI‑friendly, zero dependencies
Run the example demo: php examples/showcase.php
.
This should render the following in dark mode terminal:
Check below the Examples section for more demos.
Requirements: PHP >= 8.2 and (composer)[https://getcomposer.org/]
composer require ajaxray/ansikit
Autoloads via PSR‑4 namespace Ajaxray\AnsiKit\
.
- Getting started: docs/index.md
- Core API: AnsiTerminal
- Components: Table, Banner, Progressbar, Spinner, Choice
- Support: Input, Str, Keypress, Util
<?php
require __DIR__ . '/vendor/autoload.php';
use Ajaxray\AnsiKit\AnsiTerminal;
use Ajaxray\AnsiKit\Components\{Table, Banner, Progressbar, Choice};
$t = new AnsiTerminal();
$t->clearScreen()->cursorHome();
$t->writeStyled("Hello PHP Ninja!\n", [AnsiTerminal::TEXT_BOLD, AnsiTerminal::FG_GREEN]);
$t->fg256(202)->bg256(235)->write("256-colors")->reset()->newline();
$t->fgRGB(255,165,0)->write("Truecolor (RGB)")->reset()->newline();
$table = new Table();
$table->setHeaders('Name','Age', 'Adult?')
->addRow('Anis','41', '✅')
->addRow('Fatima', '2.5', '❌')
->render();
$banner = new Banner();
$banner->render('Deploy Complete', ['Everything shipped!']);
$bar = new Progressbar();
$bar->renderLine(75, 100, 'Loading files...');
$choice = new Choice();
$selected = $choice->prompt('Choose deployment target:', ['Production', 'Staging', 'Development']);
$t->writeStyled("Selected: {$selected}\n", [AnsiTerminal::FG_GREEN]);
Docs: AnsiTerminal
- Text attributes:
TEXT_BOLD
,TEXT_UNDERLINE
,TEXT_STRIKE
, etc. - Foreground/background colors: standard (
FG_RED
), bright (FG_BRIGHT_GREEN
),fg256($n)
,bg256($n)
,fgRGB($r,$g,$b)
,bgRGB(...)
- Cursor:
cursorTo($row, $col)
,cursorUp($n)
,hideCursor()
,saveCursor()
,enableAltBuffer()
- Output:
write($text)
,writeStyled($text, [..])
,newline($n)
Chainable style example:
$t->style(AnsiTerminal::TEXT_BOLD, AnsiTerminal::FG_YELLOW)->write('Warning!')->reset()->newline();
Docs: Table
use Ajaxray\AnsiKit\Components\Table;
(new Table())
->setHeaders('Name','Age')
->addRow('Ada', '36')
->addRow('Linus', '54')
->render();
Docs: Banner
use Ajaxray\AnsiKit\Components\Banner;
(new Banner())->render('Deploy Complete', ['Everything shipped!', 'Tag: v1.2.3']);
Docs: Progressbar
use Ajaxray\AnsiKit\Components\Progressbar;
(new Progressbar())
->barStyle([AnsiTerminal::FG_GREEN])
->percentageStyle([AnsiTerminal::TEXT_BOLD])
->labelStyle([AnsiTerminal::FG_CYAN])
->borders('[', ']')
->renderLine(50, 100, 'Processing');
Docs: Spinner
use Ajaxray\AnsiKit\Components\Spinner;
$s = new Spinner(); // or new Spinner(Spinner::ASCII)
echo $s->next(); // prints next frame
Docs: Choice
use Ajaxray\AnsiKit\Components\Choice;
// Basic usage (required choice)
$choice = new Choice();
$selected = $choice->prompt('Choose an option:', ['Option A', 'Option B', 'Option C']);
// Returns: 'Option A', 'Option B', or 'Option C'
// Optional choice (with Exit option)
$choice = new Choice();
$selected = $choice
->required(false)
->prompt('Select an action:', ['Deploy', 'Test', 'Rollback']);
// Returns: 'Deploy', 'Test', 'Rollback', or false (if Exit chosen)
// Styled choice
$choice = new Choice();
$selected = $choice
->promptStyle([AnsiTerminal::TEXT_BOLD, AnsiTerminal::FG_CYAN])
->optionStyle([AnsiTerminal::FG_GREEN])
->numberStyle([AnsiTerminal::FG_YELLOW])
->errorStyle([AnsiTerminal::FG_RED])
->exitStyle([AnsiTerminal::FG_BRIGHT_BLACK])
->prompt('Choose:', ['Option 1', 'Option 2']);
Docs: Input
use Ajaxray\AnsiKit\Support\Input;
$name = Input::line('Your name? [Anonymous] ', 'Anonymous');
$ok = Input::confirm('Proceed?', true);
$bio = Input::multiline("Enter bio. End with 'END'", 'END');
If the readline
extension is available, Input::line()
uses it for line editing/history; otherwise it falls back to STDIN
.
Docs: Str
use Ajaxray\AnsiKit\Support\Str;
$plain = Str::stripAnsi("\033[1;31mError\033[0m");
$len = Str::visibleLength("Styled \033[1mtext\033[0m");
Docs: Util
use Ajaxray\AnsiKit\Support\Util;
use Ajaxray\AnsiKit\AnsiTerminal;
$terminal = new AnsiTerminal();
Util::setTerminalTabTitle('Build in progress', $terminal);
Util::beep($terminal);
Docs: Keypress
use Ajaxray\AnsiKit\Support\Keypress;
// Blocking read (returns a normalized key constant or single char)
$key = Keypress::listen();
if ($key === Keypress::KEY_UP) { /* move up */ }
// Non-blocking read with timeout (in milliseconds)
if ($key = Keypress::listenNonBlocking(100)) {
// Works with arrows, ENTER/ESC/TAB/BACKSPACE, CTRL+A..Z, F1..F12, HOME/END/PgUp/PgDn, and more
echo Keypress::getKeyName($key); // e.g., "CTRL+C", "UP ARROW", "'a'"
}
StdoutWriter
(default): writes tophp://stdout
or a provided streamMemoryWriter
: buffer output for tests or capturing
use Ajaxray\AnsiKit\Writers\MemoryWriter;
$w = new MemoryWriter();
$t = new AnsiTerminal($w);
$t->write('hello');
echo $w->getBuffer(); // 'hello'
Run the example scripts to see things in action:
php examples/showcase.php # basic styles, table, banner, bars
php examples/progress.php # animated status + progress bar
php examples/input.php # interactive input demo
php examples/choice.php # interactive choice component demo
php examples/choice-menu.php # interactive menu system with choice
php examples/keypress.php # interactive key handling demo
php examples/keypress-advanced.php # advanced key sequences, modifiers
php examples/util.php # tab title + bell helper demo
More guides and examples: see docs/index.md.
- Windows 10+: use Windows Terminal, ConEmu, or enable VT processing for best ANSI support
- Use monospaced fonts for best alignment of box-drawing characters
- Emoji width can vary by terminal; table/banner widths are based on naive visible length
This library help with rendering basic terminal UIs with styles, colors, and cursor control. For more complex TUIs and interactive apps, you may use:
- Parsing options and flags:
- For simpler apps, $argv and getopt() should be sufficient
- For more complex apps, ulrichsg/getopt-php can be used
- Interactive menu: php-school/cli-menu
- Desktop Notification: JoliNotif
In case you are planning for a multi-command, complex app that requires guided structure and organization, you may check:
Contributions are welcome! Please:
- Fork and clone the repo
- Create a feature branch:
git checkout -b feat/your-thing
- Install dev deps:
composer install
- Run tests:
composer test
- Follow PSR‑12 and keep changes focused
- Open a PR with a clear description and before/after context
If you change public APIs, update examples and this README. Small, focused PRs are easier to review.
- ANSI-aware padding/truncation and text alignment helpers
- Color themes/palettes and named styles
- Table cell alignment and per-column styling
- Minimal TUI widgets (prompt list, select, progress spinner lines)
- Versioned with SemVer (0.x may include minor BC tweaks)
- Licensed under the MIT License — see
LICENSE
Made with ❤️ for terminal builders. If you ship something with AnsiKit, I’d love to hear about it!