ajaxray/ansikit

Tiny ANSI escape helper for terminal UIs (text styles, foreground & background colors, cursor positions, clearing) with table, progressbar, and more helpers.

v0.3.1 2025-09-22 13:57 UTC

This package is auto-updated.

Last update: 2025-09-22 13:59:22 UTC


README

AnsiKit

AnsiKit

Latest Version on Packagist Total Downloads Build Status License

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.

Features

  • 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

A Quick Primer

Run the example demo: php examples/showcase.php.
This should render the following in dark mode terminal: showcase.png

Check below the Examples section for more demos.

Installation

Requirements: PHP >= 8.2 and (composer)[https://getcomposer.org/]

composer require ajaxray/ansikit

Autoloads via PSR‑4 namespace Ajaxray\AnsiKit\.

Documentation

Quick Start

<?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]);

Usage Overview

Core: AnsiTerminal

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();

Components

Table

Docs: Table

use Ajaxray\AnsiKit\Components\Table;

(new Table())
  ->setHeaders('Name','Age')
  ->addRow('Ada', '36')
  ->addRow('Linus', '54')
  ->render();

Banner

Docs: Banner

use Ajaxray\AnsiKit\Components\Banner;

(new Banner())->render('Deploy Complete', ['Everything shipped!', 'Tag: v1.2.3']);

Progressbar

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');

Spinner

Docs: Spinner

use Ajaxray\AnsiKit\Components\Spinner;

$s = new Spinner(); // or new Spinner(Spinner::ASCII)
echo $s->next(); // prints next frame

Choice

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']);

Helpers

Input

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.

Str

Docs: Str

use Ajaxray\AnsiKit\Support\Str;

$plain = Str::stripAnsi("\033[1;31mError\033[0m");
$len   = Str::visibleLength("Styled \033[1mtext\033[0m");

Util

Docs: Util

use Ajaxray\AnsiKit\Support\Util;
use Ajaxray\AnsiKit\AnsiTerminal;

$terminal = new AnsiTerminal();
Util::setTerminalTabTitle('Build in progress', $terminal);
Util::beep($terminal);

Keypress

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'"
}

Writers

  • StdoutWriter (default): writes to php://stdout or a provided stream
  • MemoryWriter: 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'

Examples

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.

Tips & Compatibility

  • 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

Additional Resources

This library help with rendering basic terminal UIs with styles, colors, and cursor control. For more complex TUIs and interactive apps, you may use:

What if I need a full-featured CLI framework?

In case you are planning for a multi-command, complex app that requires guided structure and organization, you may check:

Contributing

Contributions are welcome! Please:

  1. Fork and clone the repo
  2. Create a feature branch: git checkout -b feat/your-thing
  3. Install dev deps: composer install
  4. Run tests: composer test
  5. Follow PSR‑12 and keep changes focused
  6. 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.

Roadmap (Ideas)

  • 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)

Versioning & License

  • 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!