CLI tool
nunomaduro/termwind avatar
nunomaduro/termwind

Termwind: Tailwind-Style Styling for PHP Command-Line Applications

🍃 In short, it's like Tailwind CSS, but for the PHP command-line applications.

2,500 stars94 forksPHPMIT

At a glance

What is it?
Termwind renders HTML-like markup with Tailwind class names into styled terminal output. It targets PHP 8.0+ console apps, and its documented scope stops where real HTML begins.
Who is it for?
Adopt Termwind if you write PHP console output and want Tailwind's class vocabulary instead of raw ANSI escape codes, and if you can accept that the README documents no rollback or fallback path for terminals that cannot render the markup. Do not adopt it if you need real HTML semantics, a browser, or a styling layer shared with a web front end; this is a terminal renderer with a fixed element list.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What problem Termwind solves, and who it is for

PHP console output is usually assembled from strings and ANSI escape sequences. The result works, but layout and colour live in the same place as the text, and changing a margin means editing a literal. Termwind takes a different route: the README describes it as "like Tailwind CSS, but for the PHP command-line applications", and the usage examples render HTML-like strings with class attributes. The audience is PHP developers building CLI tools, and specifically those already inside a Laravel or Symfony console command, since the README shows a render() call inside a Command::handle() method. If your output is a single status line, the library is more machinery than the job needs. If your output is a table, a banner, a prompt or a multi-line report, the class-based vocabulary replaces hand-written padding arithmetic with named utilities such as px-1, ml-1 and bg-green-300.

How Termwind turns class attributes into terminal output

The mechanism is a render function that accepts a string of HTML-like markup. Termwind parses the elements and their class attributes, maps each class to a terminal style or layout rule, and writes the composed result to the terminal. The README lists the supported elements, and all of them accept a class attribute: <div> and <p> default to block, <span> is an inline text container, <a> carries an href for a clickable link, and <b> and <strong> are documented as well. The class list is a subset of Tailwind's, with the same naming logic. Background and text colour follow bg-{color}-{variant} and text-{color}-{variant}. Spacing uses the familiar m- and p- families with directional variants. Layout covers display (block, flex, hidden), justify-content, width, min-width and max-width, and flex-1. Text handling includes font-bold, italic, underline, line-through, uppercase, lowercase, capitalize, snakecase and truncate. Two functions sit alongside render. style() registers or overrides a style, so style('green-300')->color('#bada55') rewrites a colour and style('btn')->apply('p-4 bg-green-300 text-white') defines a reusable class. ask() renders a prompt and returns the user's answer. terminal() exposes width(), height() and clear().

Installing Termwind and rendering a first block

The README states the requirement plainly: PHP 8.0 or higher, installed through Composer. Run the require command and Composer adds the package to your project.

bash
composer require nunomaduro/termwind

Then render markup. The function is imported from the Termwind namespace, and the string uses the same class names you would write in Tailwind. The example below comes from the README's single-line usage.

php
use function Termwind\{render};

render('<div class="px-1 bg-green-300">Termwind</div>');

You should see the word Termwind on a green background with one unit of horizontal padding. Nesting works the same way. The README's multi-line example wraps a styled div and an indented <em> inside an outer <div>, which is how you build a small report block instead of a single line.

php
render(<<<'HTML'
    <div>
        <div class="px-1 bg-green-600">Termwind</div>
        <em class="ml-1">
          Give your CLI apps a unique look
        </em>
    </div>
HTML);

Inside a Laravel or Symfony command, the README passes a rendered view to the same function, so an existing Blade or Twig template can become the source of the markup.

php
class UsersCommand extends Command
{
    public function handle()
    {
        render(
            view('users.index', [
                'users' => User::all()
            ])
        );
    }
}

Responsive classes and the fixed breakpoint scale

Termwind borrows Tailwind's responsive prefixes, and the README documents the breakpoints as terminal widths rather than pixels: sm at 64 spaces, md at 76, lg at 102, xl at 128, 2xl at 153. The README notes that all sizes are based on a font size of 15, which is how the pixel figures map onto columns. Prefix a class and it applies from that width upward, so bg-blue-500 sm:bg-red-600 renders blue in a narrow terminal and red once the terminal is at least 64 spaces wide. This is a real answer to a real problem, because a CLI cannot assume a browser window and users resize terminals freely. The trade-off is that the scale is fixed. Five breakpoints are documented, and there is no stated way to define your own, unlike Tailwind's customizing-breakpoints page that the README links to. If your layout needs a threshold at 90 columns, you are choosing between the documented steps.

Where Termwind is the wrong tool

The supported element list is short and closed. Termwind is not an HTML renderer, and the README does not present it as one: there is no table element, no form element, no heading hierarchy beyond what the class list provides. If your goal is to render a web page or an email, this library has nothing to offer. A second boundary is interactivity. ask() returns the user's answer, which covers a single prompt, but the README documents no event loop, no key handling and no redraw cycle, so a full-screen TUI with live-updating panes is outside what the project documents. Third, the README does not document a fallback path for terminals that cannot render the styling, nor a way to strip classes and emit plain text. That matters in CI logs and piped output, where escape sequences are noise. The README is silent on both, so treat detection and stripping as work you own. Finally, the class vocabulary is a subset of Tailwind's, so a class you use on the web may simply not exist here.

Termwind compared with Symfony Console's own helpers

The most direct alternative for a PHP developer is the styling already shipped with Symfony Console: the SymfonyStyle helper and the OutputFormatter tags such as <info> and <comment>. The difference is in the model. Symfony's helpers are imperative and line-oriented. You call a method or wrap a string in a tag, and the formatting is applied to that string; layout such as padding, width and alignment is expressed through the helper's API or through manual string padding. Termwind is declarative and tree-oriented. You describe a structure of nested elements with classes, and the library composes the output, so margin, padding, width, alignment and colour are properties of the tree rather than of each call. The practical consequence is that a reusable style is a named class, as in style('btn')->apply('p-4 bg-green-300 text-white'), instead of repeated tag usage. The cost is a parsing step and a dependency. For a handful of coloured lines, Symfony's helpers are less machinery. For a composed block that repeats across commands, the class-based approach pays off.

Maintenance, upgrade cost and the MIT licence

The repository is not archived, and the last push was on 2026-09-17. Recent releases listed are v2.4.0 on 2026-02-16, v2.3.3 on 2025-11-20 and v2.3.2 on 2025-10-18, so the release cadence is measured in months rather than weeks. The default branch is 2.x, which tells you the project is versioned by major line; a 3.x would be a separate branch and a separate upgrade decision. The README does not document a migration guide between majors, and there is no deprecation policy in the project's documentation, so the upgrade cost is whatever the changelog says at the time you move. For a contributor, the repository ships a docker-compose.yml with a single app service built from docker/Dockerfile, and a Makefile whose targets route commands through that container: make install runs composer install, make test runs the suite, and make test-types runs PHPStan. The licence is MIT, which is permissive and places few conditions on use and redistribution; the LICENSE.md file in the repository is the authoritative text, and this is a description of the licence identifier rather than legal advice.

Editorial conclusion

Adopt Termwind if you write PHP console output and want Tailwind's class vocabulary instead of raw ANSI escape codes, and if you can accept that the README documents no rollback or fallback path for terminals that cannot render the markup. Do not adopt it if you need real HTML semantics, a browser, or a styling layer shared with a web front end; this is a terminal renderer with a fixed element list. Before committing, run composer require nunomaduro/termwind in a throwaway project and render one <div class="px-1 bg-green-300"> to see how your target terminal handles the output.

Frequently asked questions

Is Tailwind still relevant in 2026?

The README points to tailwindcss.com/docs for the logic behind every supported class, and Termwind's own releases continue through v2.4.0 in February 2026. That is the extent of what the project documents about Tailwind's status.

What is Tailwind used for?

In Termwind's case, the Tailwind class vocabulary is used to style PHP command-line output: the README renders markup such as <div class="px-1 bg-green-300"> directly to the terminal.

Is Tailwind good or bad?

The project takes no position on this. Termwind adopts Tailwind's class naming for the terminal and links to tailwindcss.com/docs for the underlying logic, leaving the judgement to the reader.

Is Tailwind free or paid?

Termwind itself is MIT licensed, and the LICENSE.md file in the repository is the authoritative text. The README does not describe Tailwind CSS's own pricing.

Official sources

  1. License: MIT
  2. nunomaduro/termwind on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nunomaduro-termwind.svg)](https://hysenlabs.com/projects/nunomaduro-termwind)