Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pastel Laravel Package

knuckleswtf/pastel

Pastel is a lightweight PHP library for adding color and styling to console output. It offers a clean, chainable API for colors, backgrounds, and text formatting, helping you build readable, attractive CLI messages and Laravel commands.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require knuckleswtf/pastel. There is no service provider, no config file, no assets to publish. It runs in plain PHP scripts and in Artisan commands alike, which is the main reason to reach for it over Laravel's own console helpers.
  • Read the source in this order: Knuckles\Pastel\Pastel (a thin static entry point exposing Pastel::console()), then Knuckles\Pastel\ConsoleOutput, which extends Symfony's ConsoleOutput and is where every helper actually lives. If a method isn't in ConsoleOutput, it doesn't exist — don't go looking for a facade or a config.
  • The helpers you'll use 90% of the time: title(), section(), text(), listing(), unorderedList(), twoColumnDetail(), success() / warning() / error(), ask() / secret() / confirm() / choice(), progressBar(), table(), newLine().
  • First use case: take a command that currently emits a wall of $this->line() calls and give it structure. A typical rewrite:
use Knuckles\Pastel\Pastel;

$console = Pastel::console();

$console->title('Importing users');
$console->section('Step 1: Reading files');
$console->listing(['users.csv', 'roles.csv']);
$console->twoColumnDetail('Rows found', '1,203');
$console->success('Import finished in 4.2s');
  • Version note: the last release is 1.3.7 (27 March 2021), a patch on the 1.3 line — bug fixes only, no new API, no deprecations. Any ^1.3 snippet you find online still works verbatim. The package is archived, so treat it as a stable dependency, not something that will gain features.

Implementation Patterns

  • Wrap the singleton once. Pastel::console() returns a singleton ConsoleOutput. Calling it from twenty places makes the code hard to test and impossible to swap. Bind ConsoleOutput in a service provider (or add a tiny helper function) and inject it, so you can later substitute a buffered output in tests.
  • The command skeleton that pays off daily: title() → section() per phase → twoColumnDetail() for a stats/config summary → progressBar() around the main loop → success() or error() at the end. Long-running commands become scannable in CI logs instead of an undifferentiated stream.
  • Key/value output. Use twoColumnDetail($label, $value) for aligned summaries — config dumps, per-step timings, record counts. Do not hand-pad with str_pad(); the helper handles alignment and styling together.
  • Lists. listing([...]) for filenames and instructions, unorderedList([...]) for prose-style bullets. Both beat concatenating " - $item" strings, and they stay consistent if the styling changes later.
  • Progress bars:
$bar = $console->progressBar(count($rows));
$bar->start();
foreach ($rows as $row) {
    // work
    $bar->advance();
}
$bar->finish();
$console->newLine(); // Pastel does not add a trailing newline for you

The returned object is a plain Symfony\Component\Console\Helper\ProgressBar, so setFormat(), setMessage(), setRedrawFrequency(), and iterate() all work as documented by Symfony.

  • Interactivity. ask(), secret(), confirm(), and choice() are most valuable in standalone scripts — deploy helpers, scaffolding generators, one-off setup binaries — where Laravel's Prompts isn't loaded. Inside an Artisan command, prefer $this->components / $this->confirm() unless you specifically want Pastel's presentation.
  • Inline markup. text() accepts Symfony tags: $console->text('<fg=green;options=bold>OK</>'). Don't scatter tag strings through command classes — put recurring ones in class constants or a domain subclass (see below).
  • Re-rendering captured output. Artisan::call('foo') hands you a plain string with tags already rendered. If you're building a wrapper CLI, print a status line through Pastel and let the inner command write directly to the terminal, rather than trying to re-style a string that's already been formatted.
  • Extension point worth taking. Subclass ConsoleOutput and add domain helpers — summary(array $stats), step(string $label, callable $fn), rule() — then bind that class. Command classes stay free of presentation markup, and styling stays consistent as the command set grows. This is the cleanest long-term pattern with Pastel.
  • Don't mix with Laravel 9+ $this->components. Both produce their own spacing and separators. Pick one per command; mixing them yields output that looks broken even when both halves are individually correct.

Gotchas and Tips

  • Pastel::console() ignores the running command's flags. The singleton is bound to real stdout with normal verbosity and decoration, so -q, -v, and --no-ansi passed to the Artisan command are not respected — you'll still print colour into a pipe. Inside commands, construct a ConsoleOutput from $this->output->getVerbosity() and $this->output->isDecorated(), or route everything through $this->output and use Pastel only for formatting strings.
  • Testing is the real pain point. Pastel writes to the terminal stream, so Artisan::output()-style assertions won't capture it. Two workable approaches: (a) extract formatting into methods that return strings and test those, or (b) inject a BufferedOutput/custom stream and assert on the rendered text after stripping tags with preg_replace('/<[^>]+>/', '', $text).
  • Close every tag. An unclosed <fg=...> bleeds styling through every subsequent line; a mismatched close throws from Symfony's formatter. When output goes weird halfway down the screen, look for a missing </> first.
  • Stick to defined styles. Only Symfony-recognised tags are reliable: fg=, bg=, options=, plus the shorthands info, comment, question, error. Undefined tags either render literally or throw depending on the Symfony version. Register custom styles once with setStyle() if you genuinely need them.
  • Narrow terminals break alignment. twoColumnDetail(), table(), and listing() assume roughly 80–120 columns. Long labels or long values wrap and destroy the layout in CI logs and split panes. Keep left-hand labels short; truncate values yourself before passing them in.
  • Unicode and emoji in title() / success() misalign in some terminal fonts and CI viewers, and can render as garbage in log-aggregation tooling. Gate them behind an env check if the output is consumed by machines as well as humans.
  • Named arguments in ask() (ask(question: ..., default: ...)) require PHP 8. On PHP 7.x, pass them positionally or you'll get a fatal error at call time.
  • Pin ^1.3. Since the project is archived, the constraint is effectively frozen — that's fine, but skim CHANGELOG.md for the other 1.3.x patches. 1.3.7 itself is a drop-in with nothing to migrate.
  • Plan for replacement. With no maintainer, the realistic long-term move is to keep Pastel behind your own ConsoleOutput subclass or interface so that swapping to Laravel's $this->components (or a maintained fork) later is a one-class change rather than a sweep through every command.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk