tecnickcom/tc-lib-color
PHP color toolkit for parsing, converting, and normalizing GRAY, RGB/RGBA, HSL, CMYK, CIE Lab, and spot colors, with named web color lookup. Provides CSS-ready output and PDF-oriented helpers, keeping browser previews and final rendered PDFs visually consistent. Part of the TCPDF ecosystem.
Architecture fit
The package is a stateless computational library with a single namespace (\Com\Tecnick\Color) and no framework coupling — it drops cleanly into Laravel's container as an injected service. Its value concentrates in one place: normalizing color across web (CSS/RGB/HSL) and print (CMYK/Lab/Separation) surfaces. That is a real architectural seam in any app that emits both HTML and PDFs (invoicing, publishing, catalog/labeling, marketing collateral). If our Laravel app never produces press-oriented output, roughly 60–70% of the library's surface (CMYK, Lab, spot/Separation) is dead weight and a lighter alternative wins.
Integration feasibility
composer require tecnickcom/tc-lib-color plus a singleton binding in AppServiceProvider is a sub-day task. The quick-start (Web::getRgbObjFromHex() → getCssColor()) is verifiably working code, and example/index.php covers conversions. The realistic effort is not integration but adapter + test scaffolding: wrapping the vendor types behind a domain interface, adding validation at the boundary (the library assumes well-formed input — malformed hex throws rather than returning null), and building golden-value regression tests around conversions.
Technical risk
NOASSERTION. That mismatch means automated license scanners in our supply chain will flag it. LGPL for a PHP library consumed via Composer autoloading is generally treated as acceptable for proprietary apps, but this needs a legal sign-off recorded in the repo, not an assumption.Key questions
tecnickcom/tc-lib-pdf? If yes, the "adoption" decision is really a "depend on it directly and own the constraint" decision.spatie/color or league/color in the tree? Two color libraries is a policy failure waiting to happen.Stack fit
Laravel 11/12 on PHP 8.2+. No service provider ships with the package, so we author a thin one. The natural home is a ColorService domain adapter with a narrow interface (toCss(), toCmyk(), normalize()), backed by the vendor classes — this keeps the dependency swappable and confines Com\Tecnick\Color types to one directory. Use it from Blade directives, form-request validation rules (custom hex_color rule), theme/palette services, and queued PDF jobs. Do not push this into the request hot path for per-row table rendering without memoization.
Migration path Three phases, ~3–5 dev-days total:
LICENSE file, confirm the PHP constraint against our composer.json matrix, verify the PDF renderer honors CMYK/Separation.ColorService + validation rule + golden-value test suite (round-trip hex→RGB→HSL→hex, hex→CMYK→Lab, spot-color lookup, alpha handling).rgb() helpers with the adapter; codemod call sites; delete legacy helpers behind a deprecation shim.If we already have spatie/color, keep it for trivial hex↔RGB and use tc-lib-color only for the print-side conversions, or standardize on one and accept the gap.
Compatibility & sequencing
No Laravel version coupling beyond PHP — low upgrade friction. Version-pin to the 3.x line and lock via composer.lock; enable Dependabot but require a passing golden-value suite before merging minor bumps. Sequence after the PHP 8.2 baseline migration completes and, if applicable, after the PDF-engine decision is made — adopting before knowing whether the renderer honors CMYK inverts the cost/benefit.
Maintenance Expected churn is low: color math is stable and the 3.x line shows patch-level releases. Ongoing cost is dependency-update hygiene plus a periodic LGPL compliance check. Because LGPL permits forking, the mitigation for maintainer abandonment is a documented contingency: vendor-fork into an internal namespace, ~1 day of work, no legal obstacle beyond attribution.
Support No commercial SLA, no paid support tier, issue-tracker-only. Internal support model is required: one named owner, a short runbook ("which class for which conversion," "how to add a brand color," "what to do when a conversion drifts"), and a documented escalation path to upstream or fork. The published API docs are generated, not curated — expect developers to read source for edge cases like alpha parsing and spot-color naming.
Scaling Computationally trivial — microseconds per conversion, negligible memory, no I/O. It will never be a throughput bottleneck. The scaling concern is volume of conversions, not cost per conversion: catalog/theme generation loops over thousands of colors will add up. Memoize derived palettes in Redis keyed by source color + target model, and prefer batch precomputation in jobs over per-request conversion in Blade.
Failure modes and mitigations
PANTONE 185 C not recognized) → runtime failure mid-render. Mitigate with a validated allowlist of approved spot names.NOASSERTION ↔ LGPL) → compliance finding at audit. Mitigate by recording the resolved license in the SBOM at adoption time.Ramp-up Half a day for a mid-level Laravel developer to be productive; one day if they must learn Lab/spot-color semantics. The README is a single screen — onboarding depends on the example file and the generated API docs, so the internal runbook is not optional. Budget an explicit knowledge-transfer session for the on-call owner, and treat the adapter layer as the onboarding artifact: it documents the 20% of the API we actually use.
Recommendation for the decision log
Adopt conditionally, gated on a confirmed print/PDF requirement and legal sign-off on LGPL v3. Expected benefit is eliminating bespoke conversion code and cross-surface color drift; expected cost is ~3–5 dev-days plus a permanent single-maintainer and license-compliance watch item. If the print requirement does not exist, defer — spatie/color or league/color covers web-only needs with better documentation and broader adoption.
How can I help you explore Laravel packages today?