PHPackages                             peripteraptos/hyperwind - 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. peripteraptos/hyperwind

ActiveLibrary

peripteraptos/hyperwind
=======================

v1.0.2(7mo ago)0261MITPHP

Since Nov 17Pushed 7mo agoCompare

[ Source](https://github.com/peripteraptos/hyperwind)[ Packagist](https://packagist.org/packages/peripteraptos/hyperwind)[ RSS](/packages/peripteraptos-hyperwind/feed)WikiDiscussions main Synced today

READMEChangelog (2)Dependencies (1)Versions (4)Used By (1)

Hyperwind
=========

[](#hyperwind)

Hyperwind is a tiny PHP helper to build Tailwind (or any utility CSS) class strings using **variants** and **compound variants**, and to render small “styled components” directly as HTML strings.

It’s especially handy in server-side rendered PHP apps where you want a clean, declarative way to describe visual variants without scattering class strings everywhere.

> **Inspired by:**
> This package is based on the ideas and API of the Typescript library **[Windstitch](https://github.com/vinpac/windstitch/tree/main)**. All credit for the original concept goes to that project.

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

[](#installation)

You can install the package via composer:

```
composer require peripteraptos/hyperwind
```

API Overview
------------

[](#api-overview)

Hyperwind exposes three main functions:

- `wx(array $config): callable` – build a **class name factory**
- `styled(string $as, array $config = []): callable` – build a **small “styled component”** that renders HTML
- `evaluate_classname(...)` – internal helper used by both; you usually don’t need to call this directly

All functions live in the `Hyperwind` namespace.

`wx` – class name builder
-------------------------

[](#wx--class-name-builder)

`wx` lets you define base classes, **variants**, **default variants**, and **compound variants**, and returns a callable that will produce the final class string.

```
use function Hyperwind\wx;

$buttonClass = wx([
    'className' => 'inline-flex items-center justify-center rounded',
    'variants' => [
        'variant' => [
            'primary'   => 'bg-blue-600 text-white',
            'secondary' => 'bg-gray-100 text-gray-900',
        ],
        'size' => [
            'sm' => 'text-xs px-2 py-1',
            'md' => 'text-sm px-3 py-2',
        ],
    ],
    'defaultVariants' => [
        'variant' => 'primary',
        'size'    => 'md',
    ],
    'compoundVariants' => [
        [
            'variant' => 'primary',
            'size'    => 'md',
            'class'   => 'shadow',
        ],
    ],
]);

// With explicit props
$classes = $buttonClass([
    'variant' => 'secondary',
    'size'    => 'sm',
]);
// "inline-flex items-center justify-center rounded bg-gray-100 text-gray-900 text-xs px-2 py-1"

// With defaults (also applies compound variant)
$classesDefault = $buttonClass();
// "inline-flex items-center justify-center rounded bg-blue-600 text-white text-sm px-3 py-2 shadow"
```

**Config keys:**

- `className` – base classes, always included
- `variants` – array of variant name → map of value → class string, or a callable `fn($value, $props, $variants): string`
- `defaultVariants` – default value per variant when not passed in props
- `compoundVariants` – array of objects like:

    ```
    [
        'variant' => 'primary',
        'size'    => 'lg',
        'class'   => 'shadow-lg',
        // optional: 'defaultTo' => ['size' => 'lg', ...]
    ]
    ```

    The most specific matching compound (with most keys) wins.

`styled` – HTML “components” with variants
------------------------------------------

[](#styled--html-components-with-variants)

`styled` wraps `wx` and renders HTML elements with attributes. It returns a callable that you can use like a tiny component:

```
use function Hyperwind\styled;

$Button = styled('button', [
    'className' => 'inline-flex items-center justify-center rounded',
    'variants' => [
        'variant' => [
            'primary'   => 'bg-blue-600 text-white',
            'secondary' => 'bg-gray-100 text-gray-900',
            'link'      => 'text-blue-600 underline bg-transparent',
        ],
        'size' => [
            'sm' => 'text-xs px-2 py-1',
            'md' => 'text-sm px-3 py-2',
        ],
    ],
    'defaultVariants' => [
        'variant' => 'primary',
        'size'    => 'md',
    ],
    'defaultProps' => [
        'type' => 'button',
    ],
]);

echo $Button([
    'variant'  => 'secondary',
    'size'     => 'sm',
    'id'       => 'save-button',
    'children' => 'Save',
]);
```

Output (simplified):

```

  Save

```

### Special props

[](#special-props)

- `children` – inner HTML/text of the element
- `as` – change the tag name:

    ```
    echo $Button([
        'as'       => 'a',
        'href'     => '/profile',
        'variant'  => 'link',
        'children' => 'Profile',
    ]);
    // Profile
    ```
- Variant keys (e.g. `variant`, `size`) are **used only for class generation** and are **not rendered** as HTML attributes.

### Void tags

[](#void-tags)

If you use a void tag like `img`, `input`, `br`, etc., `styled` will not render a closing tag or children:

```
$Img = styled('img', [
    'className' => 'rounded',
    'variants' => [
        'size' => [
            'thumb' => 'w-16 h-16',
            'full'  => 'w-full',
        ],
    ],
    'defaultVariants' => [
        'size' => 'thumb',
    ],
]);

echo $Img([
    'src' => '/image.jpg',
    'alt' => 'Test',
    'children' => 'IGNORED', // ignored for void tags
]);
```

Gives:

```

```

`evaluate_classname` (low-level)
--------------------------------

[](#evaluate_classname-low-level)

You usually don’t need this directly; it’s what powers `wx` and `styled`.

Signature:

```
use function Hyperwind\evaluate_classname;

string evaluate_classname(
    array $props,
    array $variants,
    array $defaultVariants = [],
    array $compoundVariants = [],
    string $defaultClassName = ''
): string
```

It accepts the same structures as shown above and returns a composed class string.

Testing
-------

[](#testing)

If you want to run the tests:

```
composer install
./vendor/bin/phpunit
```

Credits
-------

[](#credits)

Hyperwind is **based on and heavily inspired by** the JavaScript library **[Windstitch](https://github.com/vinpac/windstitch/tree/main)**. Concept, naming, and overall API design originate from that project – this package is a PHP adaptation.

###  Health Score

31

—

LowBetter than 66% of packages

Maintenance63

Regular maintenance activity

Popularity9

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 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 ~1 days

Total

3

Last Release

226d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3edb2b99a9e09432c08d2d022c7d8329b2d60580da82db3ff19c7cc5714a9d6f?d=identicon)[peripterptos](/maintainers/peripterptos)

---

Top Contributors

[![peripteraptos](https://avatars.githubusercontent.com/u/23555520?v=4)](https://github.com/peripteraptos "peripteraptos (13 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/peripteraptos-hyperwind/health.svg)

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

PHPackages © 2026

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