PHPackages                             aspectus/terminal - 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. [CLI &amp; Console](/categories/cli)
4. /
5. aspectus/terminal

ActiveLibrary[CLI &amp; Console](/categories/cli)

aspectus/terminal
=================

A terminal abstraction

v0.1.7(2y ago)247[2 PRs](https://github.com/Aspectus-PHP/terminal/pulls)1MITPHPCI passing

Since Jun 3Pushed 1y ago1 watchersCompare

[ Source](https://github.com/Aspectus-PHP/terminal)[ Packagist](https://packagist.org/packages/aspectus/terminal)[ RSS](/packages/aspectus-terminal/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (4)Versions (10)Used By (1)

Terminal device
---------------

[](#terminal-device)

This is an open-source PHP package providing a small abstraction for the terminal. The idea is to see the terminal as a device, which can perform both input and output. The package relies on Amphp to provide non-blocking handling of the streams and an event dispatcher to handle input.

Furthermore, this package also provides an abstraction for Xterm that is using the terminal device, supporting most of the escape control sequences in the manual (patch #379) as well dispatching events for handling mouse movement.

Usage
-----

[](#usage)

### Basic Output

[](#basic-output)

```
use Aspectus\Terminal\TerminalDevice;

$device = new TerminalDevice();

$device->write("This and that");    // will output "This and that" in STDOUT
$device->error("There was some error");     // will output in STDERR
```

### Basic Input

[](#basic-input)

For handling the input you can rely on the supplied EventDispatcher.

```
$device->subscribe(
    InputEvent::class,
    function (InputEvent $event) {
        $event->device->write('Read: ' . bin2hex($event->data) . PHP_EOL);
    }
);

$device->subscribe(
    InputEvent::class,
    function (InputEvent $event) {
        if ($event->data === 'q') {
            exit();
        }
    }
);
```

### Device Input Events

[](#device-input-events)

The current implementation will distinguish between normal input events (InputEvent) and input that is an escape sequence (EscapeSequenceEvent), so your listeners can attach to the correct one. Unless you need to read some escape sequence that the terminal sends back to you, you probably need to listen to InputEvent.

`InputEvent` - the default event that is emitted.

`EscapeSequenceEvent` - this is emitted when input starts with an escape sequence

All events hold a reference to the device that dispatched them into the `$event->device` property.

For `Xterm events` see below.

### Event Factory

[](#event-factory)

The device by default has a minimal implementation for creating new events. You can supply your own by implementing the `EventFactoryInterface`.

```
interface EventFactoryInterface
{
    /**
     * Optionally creates an event to be dispatched
     *
     * @param string $received
     * @return InputEvent|null
     */
    public function createEvent(string $received): ?InputEvent;
}
```

### Xterm abstraction

[](#xterm-abstraction)

The package comes with an abstraction for Xterm that provides named methods to escape sequences in a fluent interface. `Xterm` will buffer every call and write it to the device when `flush()` is called or return it as a `string` when `getBuffered()` is called.

```
$xterm = new \Aspectus\Terminal\Xterm();

$xterm
    // we reset colors in the beginning
    ->default()
    ->bgDefault()
    ->normal()
    ->eraseDisplay()

    // position for first message
    ->moveCursorTo(5,5)

    // set style
    ->red()
    ->bgWhite()

    // write a message
    ->write('Hello world!')

    // position for second message
    ->moveCursorTo(8, 10)

    // set style
    ->bold()
    ->brightYellow()
    ->bgBlue()

    // return instructions
    ->write('This is an Xterm abstraction!')

    // write the whole buffer
    ->flush()
```

### Xterm Input events

[](#xterm-input-events)

Using the Xterm abstraction will add a different `EventFactory` implementation which will emit some additional events when they are received.

`SpecialKeyEvent` is emitted when function or arrow keys are pressed. The `data` property of the event is mapped to a generic format, indicating function keys like `` and arrow keys like ``, ``.

`MouseInputEvent` - is emitted when mouse tracking is enabled and provides properties like `x` and `y` as well as methods for the buttons (like `button1()`) to get information about which buttons were pressed.

`MouseFocusEvent` - is emitted when mouse tracking and focus tracking have been enabled and provides a way to attach to an event that will trigger when the window loses focus or gains it again.

### More usage examples

[](#more-usage-examples)

More usage examples can be found in the `examples/` directory.

Contribute
----------

[](#contribute)

Everyone is welcome to contribute, please see `CONTRIBUTE.md` for more information.

Licence
-------

[](#licence)

MIT

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance32

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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.

###  Release Activity

Cadence

Every ~9 days

Total

7

Last Release

1022d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/08c186b51dd688533c147618687a391ac764aafcff5efc2cbb2005cc28befef6?d=identicon)[thgs](/maintainers/thgs)

---

Top Contributors

[![thgs](https://avatars.githubusercontent.com/u/8940963?v=4)](https://github.com/thgs "thgs (26 commits)")

---

Tags

amphpansiphpterminalvt100xtermasyncasynchronousterminalansivt100xterm

### Embed Badge

![Health badge](/badges/aspectus-terminal/health.svg)

```
[![Health](https://phpackages.com/badges/aspectus-terminal/health.svg)](https://phpackages.com/packages/aspectus-terminal)
```

###  Alternatives

[symfony/console

Eases the creation of beautiful and testable command line interfaces

9.8k1.1B11.3k](/packages/symfony-console)[clue/term-react

Streaming terminal emulator, built on top of ReactPHP.

10410.2M2](/packages/clue-term-react)[amphp/parallel

Parallel processing component for Amp.

84746.2M74](/packages/amphp-parallel)[league/climate

PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.

1.9k14.0M273](/packages/league-climate)[amphp/sync

Non-blocking synchronization primitives for PHP based on Amp and Revolt.

18852.8M39](/packages/amphp-sync)[clue/stdio-react

Async, event-driven console input &amp; output (STDIN, STDOUT) for truly interactive CLI applications, built on top of ReactPHP

19810.2M27](/packages/clue-stdio-react)

PHPackages © 2026

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