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

Colour Laravel Package

innmind/colour

A small PHP library for representing and manipulating colours as immutable value objects. Parse hex, RGB and HSL values, convert between colour models and compare colours with a clean API that fits the Innmind ecosystem.

View on GitHub
Deep Wiki
Context7

Getting Started

innmind/colour is a standalone, framework-agnostic value-object library for colour manipulation — it is not a Laravel package. There is no service provider, facade, or config file, so you wire it in yourself (usually via a small palette service bound in a provider).

composer require innmind/colour

Check the PHP constraint before anything else. Release 5.2.0 dropped PHP 8.4 support. If your Laravel app runs on PHP 8.4 (the default for recent Laravel installs), Composer will silently keep you on 5.1.0 — or fail if you've pinned ^5.2:

composer why-not innmind/colour 5.2.0
composer show innmind/colour | grep -i versions

Either pin "innmind/colour": "^5.1" deliberately while on 8.4, or set config.platform.php to the version you actually deploy on so resolution is deterministic across CI and production.

Where to look first: the Innmind\Colour\Colour interface, then the concrete immutable classes (RGBA, HSL, CMYK, …). Once you understand that every "setter" returns a new object, the rest of the API falls into place.

First use case — theme colours. Take a brand hex from config, derive a hover state and a muted variant, and emit CSS variables:

use Innmind\Colour\RGBA;

$brand = RGBA::of(59, 130, 246);          // #3b82f6
$hover = $brand->withAlpha(0.85);

echo $brand->toString();                   // hex representation

That single flow — parse a colour, transform it, serialise it — is 80% of real-world usage.

Implementation Patterns

Wrap it in a palette service, not raw calls in views. Colour generation is pure, deterministic, and cacheable; treat it as config, not rendering logic.

// app/Support/Palette.php
final class Palette
{
    /** @return array<string, string> */
    public function for(string $hex): array
    {
        $base = RGBA::fromString($hex);

        return [
            'base'    => $base->toString(),
            'hover'   => $base->withAlpha(0.9)->toString(),
            'subtle'  => $base->withAlpha(0.1)->toString(),
        ];
    }
}

Bind it as a singleton and feed it from config/theme.php. Then generate the CSS variable block once and cache it (Cache::rememberForever, invalidated by a config-keyed hash) rather than recomputing per request.

Eloquent cast for stored colours. Colours in the DB are usually char(7) hex or a nullable string. A custom cast keeps domain objects in your models while persisting a plain string:

final class ColourCast implements CastsAttributes
{
    public function get($model, $key, $value, $attributes): ?RGBA
    {
        return $value === null ? null : RGBA::fromString($value);
    }

    public function set($model, $key, $value, $attributes): array
    {
        return [$key => $value?->toString()];
    }
}

Validation rule. Users type #fff, #ffffff, rgb(...). Normalise on the way in with a Rule object that tries to construct the value object and fails cleanly — this keeps malformed strings out of your casts and out of toString() round-trips.

API resources. Never let the value object leak into JSON implicitly; JsonResource should return the string form under a stable key ("color": "#3b82f6"), otherwise a library upgrade changes your public payload.

Contrast/accessibility. The package gives you colour maths, not WCAG. Compute relative luminance yourself (or via a tiny helper) on the RGBA channels, and use it to pick black/white text on a dynamic background — the classic use case for admin-configurable brand colours.

Image and PDF generation. Dompdf/GD/Imagick all want [r, g, b] or hex. Read the individual channels off the value object once and hand arrays to the downstream library; don't convert back and forth between colour spaces inside a render loop.

Gotchas and Tips

Immutability is the #1 footgun. $colour->withAlpha(0.5); on its own line does nothing. Every transformation returns a new instance — if your colours "aren't changing", you forgot the reassignment. Linters won't catch this.

PHP 8.4 support was dropped in 5.2.0. This is the only change in the release, and it's a support-matrix change, not a code change. Two things to verify:

  • Whether the PR raised the minimum PHP version rather than excluding 8.4 specifically — the title is ambiguous, and a raised floor is the far more common Composer outcome. Read composer.json's require.php in the published tag.
  • Whether your CI matrix includes 8.4. A green build on 8.3 does not prove 5.2.0 works on your 8.4 production runtime.

Given the release adds no features, there is no reason to upgrade unless you're on a supported PHP version and want to stay current. Pin ^5.1 if you're on 8.4 and revisit when a subsequent release restores it.

Out-of-range channels throw. Constructing an RGBA with 300 or an alpha outside 0–1 fails rather than clamping. Always validate user input before construction, and wrap config reads in a try/catch during boot so a bad .env value doesn't 500 every request.

Alpha units differ by context. Alpha here is typically a 0–1 float; CSS also uses 0–1, but many DB columns and design tools use 0–255. Pick one convention at the boundary and convert exactly once.

Hex round-tripping loses information. Converting RGB → HSL → RGB and re-serialising can shift a channel by a unit due to rounding. If you store a hex string and later display the "original" colour, keep the source string; don't reconstruct it through a colour-space conversion.

toString() output format matters. Check whether it emits #rrggbb or bare rrggbb, and how it handles alpha (some libraries emit #rrggbbaa, which older browsers and some CSS preprocessors reject). Normalise in your serialisation layer rather than trusting the default everywhere.

No auto-discovery, no facade — treat that as a feature. Because there's no global state or container coupling, the package is trivially testable and safe in queued jobs. Keep it that way: pass colour strings into jobs, not value objects, since serialising third-party objects into queue payloads breaks on library upgrades.

Extension points are your own wrappers. There is no Laravel-side hook to extend. If you need clamping, named palettes, or Tailwind-style scale generation (50, 100, …, 900), build a thin Palette/Shade layer on top and keep the upgrade surface to that one class — it makes future version bumps (like this one) a one-line constraint change instead of a codebase-wide audit.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons