Polyscope - The agent-first dev environment for Laravel

Ansikit

Ansikit stats

Downloads
3
Stars
4
Open Issues
0
Forks
0

View on GitHub →

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

AnsiKit

AnsiKit

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:

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!

ajaxray photo

I am a web application architect, proficient at requirement analysis, sophisticated solution design and scalable application development.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.


Ajaxray Ansikit Related Articles

Creating a Password Generator image

Creating a Password Generator

Read article
Livewire Added File Upload Support (And It’s Kind of a Game-Changer) image

Livewire Added File Upload Support (And It’s Kind of a Game-Changer)

Read article
The Certification of Competence for Laravel logo

The Certification of Competence for Laravel

A community-driven, proctored assessment across 4 levels designed to validate real-world Laravel knowledge, from Junior to mastery-level Artisan. Official Vue.js, Official Nuxt, Angular, React, JS certifications also available.

The Certification of Competence for Laravel
CodeKudu logo

CodeKudu

Stand-ups, Retrospectives, and 360° Feedback for the entire team. 50% off with code LARAVELNEWS.

CodeKudu
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Statamic logo

Statamic

The drop-in ready Laravel CMS you’re been waiting for. Go full-stack or headless, flat file or database – it’s up to you.

Statamic