PHPackages                             pdphilip/omniterm - 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. pdphilip/omniterm

ActiveLibrary

pdphilip/omniterm
=================

This is my package OmniTerm

v3.0.0(1mo ago)134.4k↑16%[1 PRs](https://github.com/pdphilip/omniterm/pulls)6MITPHPPHP ^8.2CI passing

Since Sep 17Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/pdphilip/omniterm)[ Packagist](https://packagist.org/packages/pdphilip/omniterm)[ Docs](https://github.com/pdphilip/omniterm)[ GitHub Sponsors](https://github.com/PDPhilip)[ RSS](/packages/pdphilip-omniterm/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (28)Versions (18)Used By (6)

[![OmniTerm](https://camo.githubusercontent.com/73fcc52fa9e463c34173c02b25b7fe387f937d1d97b0eca9b21040cf056cd91b/68747470733a2f2f63646e2e736e6970666f726d2e696f2f70647068696c69702f6f6d6e697465726d2f6f6d6e692d7465726d2d62616e6e65722e706e67)](https://camo.githubusercontent.com/73fcc52fa9e463c34173c02b25b7fe387f937d1d97b0eca9b21040cf056cd91b/68747470733a2f2f63646e2e736e6970666f726d2e696f2f70647068696c69702f6f6d6e697465726d2f6f6d6e692d7465726d2d62616e6e65722e706e67)[![Latest Version on Packagist](https://camo.githubusercontent.com/21b52882bfb920509896eecfa5f37b46405584f75587fdfec16c594ccf29cdd1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f70647068696c69702f6f6d6e697465726d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pdphilip/omniterm)[![GitHub Tests Action Status](https://camo.githubusercontent.com/b3b6afd07b4e682152f488e37e77f6aff2013c153ae13edb3398f279a847d8a3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f70647068696c69702f6f6d6e697465726d2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/pdphilip/omniterm/actions?query=workflow%3Arun-tests+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/b258601910fb6beae683f052520d6ade605b3caec03950712448f5aa81be5fc9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70647068696c69702f6f6d6e697465726d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pdphilip/omniterm)

**Terminal UI toolkit for Laravel**

Rich CLI output using HTML and Tailwind CSS classes, rendered as ANSI in your terminal.

[![Progress Bars](docs/gifs/progress-bars.gif)](docs/gifs/progress-bars.gif)

---

About
-----

[](#about)

OmniTerm is a terminal rendering engine for Laravel. Write your CLI output as HTML with Tailwind CSS classes and OmniTerm compiles it to ANSI escape sequences.

The Tailwind-for-terminal concept was pioneered by [Termwind](https://github.com/nunomaduro/termwind). OmniTerm builds on that idea with its own rendering engine that adds:

- **16 million color support** - full RGB truecolor, with automatic 256-color fallback for older terminals
- **Gradients** - `bg-gradient-to-r`, `from-{color}`, `via-{color}`, `to-{color}` for smooth per-character color transitions
- **Arbitrary RGB classes** - `text-[R,G,B]` and `bg-[R,G,B]` for computed/dynamic colors
- **Content repeat** - `content-repeat-[char]` to fill widths with box-drawing characters

On top of the rendering engine, OmniTerm ships with a set of pre-built components for common CLI patterns: status messages, data tables, progress bars, spinners, live tasks, and an interactive split-pane browser.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, or 12

Installation
------------

[](#installation)

```
composer require pdphilip/omniterm
```

---

Built-in Components
-------------------

[](#built-in-components)

Add the `HasOmniTerm` trait to any Artisan command:

```
use OmniTerm\HasOmniTerm;

class MyCommand extends Command
{
    use HasOmniTerm;

    public function handle()
    {
        $this->omni->success('Ready');
    }
}
```

### Status Messages

[](#status-messages)

One-line status badges:

```
$this->omni->success('Task completed');     // Green GOOD badge
$this->omni->error('Something went wrong'); // Red FAIL badge
$this->omni->warning('Check your config');  // Amber WARN badge
$this->omni->info('Processing...');         // Blue INFO badge
$this->omni->disabled('Feature off');       // Gray OFF badge
```

Detailed status blocks with title, message, and help lines:

```
$this->omni->statusSuccess('Migration Complete', 'All 42 records processed', ['Run cache:clear']);
$this->omni->statusError('Connection Failed', 'Could not reach database', ['Check .env', 'Ensure MySQL is running']);
```

[![Status Messages](./docs/gifs/status-messages.gif)](./docs/gifs/status-messages.gif)

### Data Tables

[](#data-tables)

Key-value rows with status indicators:

```
$this->omni->tableHeader('Setting', 'Value', 'Notes');
$this->omni->tableRow('Database', 'mysql', 'Production server');
$this->omni->tableRowSuccess('Connection', 'Active');
$this->omni->tableRowError('SSL Certificate', 'Expired');
$this->omni->tableRowWarning('Memory', '85% used');
```

[![Data Tables](./docs/gifs/data-tables.gif)](./docs/gifs/data-tables.gif)

### Visual Elements

[](#visual-elements)

Title bars, boxes, and horizontal rules:

```
$this->omni->titleBar('My Application', 'sky');
$this->omni->roundedBox('Welcome', 'text-cyan-500', 'text-white');
$this->omni->hr();
$this->omni->hrSuccess();
```

[![Visual Elements](./docs/gifs/visual-elements.gif)](./docs/gifs/visual-elements.gif)

### Progress Bars

[](#progress-bars)

Fluent builder API with three styles: simple, framed, and gradient. Color steps transition from rose through amber to emerald as progress increases.

```
$bar = $this->omni->progressBar(100)->framed()->steps();
$bar->start();

foreach ($items as $item) {
    // work...
    $bar->advance();
}

$bar->finish();
```

Other variants:

```
$this->omni->progressBar(50);                              // Simple bar (sky)
$this->omni->progressBar(50)->steps();                     // Simple with color steps
$this->omni->progressBar(50)->framed()->color('indigo');   // Framed with custom color
$this->omni->progressBar(50)->gradient();                  // Gradient (amber → emerald)
$this->omni->progressBar(50)->framed()->gradient('rose', 'sky'); // Custom gradient
```

[![Progress Bars](./docs/gifs/progress-bars.gif)](./docs/gifs/progress-bars.gif)

### Live Tasks

[](#live-tasks)

Run a callback in a background process with an animated spinner:

```
use OmniTerm\Async\Spinner;

$this->omni->newLoader(Spinner::Sand);

$result = $this->omni->runTask('Processing data...', function () {
    sleep(3);
    return ['state' => 'success', 'message' => 'Done'];
});
```

One-liner with `task()`:

```
$this->omni->task('Processing batch job', function () {
    sleep(3);
    return ['state' => 'success', 'message' => 'Batch complete', 'details' => '500 records'];
}, Spinner::DotsCircle, ['text-indigo-500', 'text-violet-500']);
```

For fine-grained control with live-updating counters:

```
$task = $this->omni->liveTask('Processing records', spinner: Spinner::Dots3)
    ->row('Created', 0, 'text-sky-500')
    ->row('Updated', 0, 'text-emerald-500')
    ->row('Skipped', 0, 'text-amber-500')
    ->row('Failed', 0, 'text-rose-500');

// Simulate 5 chunked batches
for ($batch = 0; $batch < 5; $batch++) {
    $result = $task->run(function () {
        usleep(800000);

        return [
            'created' => rand(10, 50),
            'updated' => rand(5, 20),
            'skipped' => rand(0, 5),
            'failed' => rand(0, 2),
        ];
    });

    $task->increment('Created', $result['created']);
    $task->increment('Updated', $result['updated']);
    $task->increment('Skipped', $result['skipped']);
    $task->increment('Failed', $result['failed']);
}

$task->finish('Processing complete');
```

The `Spinner` enum provides 10 animation types: `Dots`, `Dots2`, `Dots3`, `DotsCircle`, `Sand`, `Clock`, `Material`, `Pong`, `Progress`, `ProgressLoader`.

### Interactive Browser

[](#interactive-browser)

Split-pane TUI: scrollable list on the left, detail view on the right. Items can be closures (rendered with full omni output), associative arrays (auto-formatted), or plain arrays.

```
+-- Server Dashboard ---------------+-----------------------------------+
| > web-01                          |  ✓ GOOD  Healthy                  |
|   web-02                          |  All checks passing               |
|   db-primary                      |                                   |
|   cache-01                        |  Metric    Value                  |
+-----------------------------------+  CPU        23%                   |
                                    +-----------------------------------+
  ↑/↓ Navigate  Enter Select  q/Esc Exit

```

```
use OmniTerm\OmniTerm;

$selected = $this->omni->browse('Server Dashboard', [
    'web-01' => function (OmniTerm $omni) {
        $omni->statusSuccess('Healthy', 'All checks passing');
        $omni->tableHeader('Metric', 'Value');
        $omni->tableRowSuccess('CPU', '23%');
        $omni->tableRow('Memory', '4.2 GB / 8 GB');
    },
    'db-primary' => ['status' => 'running', 'cpu' => '45%', 'memory' => '28 GB / 32 GB'],
]);
// Returns selected key, or null on Esc
```

### Interactive Prompts

[](#interactive-prompts)

```
$name = $this->omni->ask('What is your name?');
$color = $this->omni->ask('Choose a color:', ['red', 'green', 'blue']);
```

---

DIY - The Rendering Engine
--------------------------

[](#diy---the-rendering-engine)

The built-in components are just Blade templates compiled through OmniTerm's rendering engine. You can use the same engine directly to build anything.

### `render()`

[](#render)

Write HTML with Tailwind classes, get ANSI output:

```
$this->omni->render('
    PASS
    Database connection verified
    12ms
');
```

### `liveView()`

[](#liveview)

Redraws in place, for live-updating displays:

```
$live = $this->omni->liveView('Starting...');

for ($i = 1; $i reRender("Progress: {$i}%");
    usleep(50000);
}

$this->omni->endLiveView();
```

### `parse()`

[](#parse)

Convert HTML to an ANSI string without printing:

```
$ansi = $this->omni->parse('Hello');
```

### `terminal()`

[](#terminal)

Terminal dimensions:

```
$width = $this->omni->terminal()->getWidth();
$height = $this->omni->terminal()->getHeight();
```

### Supported Classes

[](#supported-classes)

[![Tailwind Classes](docs/gifs/tailwind-classes.gif)](docs/gifs/tailwind-classes.gif)

#### Layout

[](#layout)

ClassEffect`flex`Horizontal layout`flex-1`Fill remaining space`w-{n}`Fixed width in characters`space-x-{n}`Gap between children#### Spacing

[](#spacing)

ClassEffect`px-{n}`, `pl-{n}`, `pr-{n}`Horizontal padding`mx-{n}`, `ml-{n}`, `mr-{n}`Horizontal margin`mt-{n}`, `mb-{n}`Vertical margin (blank lines)#### Typography

[](#typography)

ClassEffect`font-bold`Bold`text-center`Center-align`text-right`Right-align#### Colors

[](#colors)

All [Tailwind colors](https://tailwindcss.com/docs/customizing-colors) with shades 50-950: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose.

ClassEffect`text-{color}-{shade}`Text color, e.g. `text-sky-500``bg-{color}-{shade}`Background color, e.g. `bg-red-600``text-[R,G,B]`Arbitrary RGB text, e.g. `text-[255,100,50]``bg-[R,G,B]`Arbitrary RGB background#### Gradients

[](#gradients)

Per-character color interpolation across an element's width.

ClassEffect`bg-gradient-to-r`Left-to-right gradient`bg-gradient-to-l`Right-to-left gradient`from-{color}-{shade}`Start color`via-{color}-{shade}`Midpoint color`to-{color}-{shade}`End color```
$this->omni->render('

        Smooth gradient

');
```

#### Content

[](#content)

ClassEffect`content-repeat-[char]`Repeat character to fill width### Color Mode Detection

[](#color-mode-detection)

OmniTerm auto-detects your terminal's color capability:

- **Truecolor (16M)** - full RGB. iTerm2, Kitty, WezTerm, most modern terminals.
- **256-color** - automatic fallback for older terminals (e.g. Apple Terminal). Colors mapped to nearest match.

No configuration needed.

### Using Blade Templates

[](#using-blade-templates)

Since OmniTerm is a Laravel package, you can write your CLI output as Blade views and render them through the engine. This is how all the built-in components work:

```
// resources/views/cli/deploy-status.blade.php

    {{ $badge }}
    {{ $message }}

// In your command
$this->omni->view('cli.deploy-status', [
    'badge' => 'DEPLOY',
    'color' => 'emerald',
    'message' => 'Production updated',
]);
```

---

Samples
-------

[](#samples)

OmniTerm includes sample commands for every feature. Copy them into your app:

```
mkdir -p app/Console/Commands/OmniTermSamples
cp vendor/pdphilip/omniterm/samples/Commands/*.php app/Console/Commands/OmniTermSamples/
```

Update the namespace in each file to `App\Console\Commands\OmniTermSamples`, then:

```
php artisan omniterm:full-demo          # One of every feature
php artisan omniterm:status-messages    # Status messages
php artisan omniterm:data-tables        # Key-value tables
php artisan omniterm:visual-elements    # Boxes and horizontal rules
php artisan omniterm:title-bars         # Title bar colors
php artisan omniterm:progress-bars      # All progress bar styles
php artisan omniterm:spinners           # All 10 spinner animations
php artisan omniterm:async-tasks        # Async task execution
php artisan omniterm:live-task-demo     # LiveTask with feedback rows
php artisan omniterm:browser-demo       # Interactive split-pane browser
php artisan omniterm:tailwind-classes   # Every supported CSS class
php artisan omniterm:interactive        # Interactive prompts
php artisan omniterm:custom-colors      # Custom color schemes
php artisan omniterm:global-functions   # Render & live view functions
```

---

Testing
-------

[](#testing)

```
composer test        # Lint + PHPStan + Pest
composer test:unit   # Pest only
composer types       # PHPStan only
composer format      # Laravel Pint
```

License
-------

[](#license)

MIT. See [License File](LICENSE.md).

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance89

Actively maintained with recent releases

Popularity31

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 80.6% 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 ~39 days

Recently: every ~7 days

Total

15

Last Release

55d ago

Major Versions

v0.0.1 → v1.0.02024-09-18

v1.0.6 → v2.0.02026-02-18

v2.1.1 → 3.x-dev2026-03-24

### Community

Maintainers

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

---

Top Contributors

[![pdphilip](https://avatars.githubusercontent.com/u/6921550?v=4)](https://github.com/pdphilip "pdphilip (50 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (7 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

laravelPDPhilipomniterm

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/pdphilip-omniterm/health.svg)

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

###  Alternatives

[laravel/reverb

Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.

1.6k9.4M48](/packages/laravel-reverb)[laravel-zero/framework

The Laravel Zero Framework.

3371.4M369](/packages/laravel-zero-framework)[hirethunk/verbs

An event sourcing package that feels nice.

513162.9k6](/packages/hirethunk-verbs)[nativephp/mobile

NativePHP for Mobile

82724.0k43](/packages/nativephp-mobile)[wnx/laravel-backup-restore

A package to restore database backups made with spatie/laravel-backup.

203330.1k2](/packages/wnx-laravel-backup-restore)[spatie/laravel-site-search

A site search engine

300129.1k](/packages/spatie-laravel-site-search)

PHPackages © 2026

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