Intelligent color utilities for accessibility, contrast optimization, and visual harmony — for Flutter.
A Flutter/Dart port of the SwiftUI package Garnish by Aether. All credit for the original concept, algorithms, and API design goes to the original author. See Credits.
- Contrast Optimization — Generate colors that meet WCAG accessibility standards
- Dynamic Color Adaptation — Colors that work beautifully in light and dark themes
- Mathematical Color Analysis — Precise luminance, brightness, and contrast calculations
- Smart Color Generation — Create contrasting shades and optimized color combinations
- Font Weight Optimization — Improved readability through accessibility-first recommendations
- Palette Expansion — Grow a few colors into a harmonious palette (optional module)
Add Garnish to your pubspec.yaml:
dependencies:
garnish:
git: https://github.com/rehmatsg/garnish.gitThen run flutter pub get.
Targets Flutter
>=3.27/ Dart>=3.6and uses the modern floating-pointColorAPI (.r/.g/.b/.a,Color.from).
See Getting Started for a detailed walkthrough.
import 'package:flutter/material.dart';
import 'package:garnish/garnish.dart';
// Generate an accessible text color for any background.
final textColor = Garnish.contrastingColor(Colors.black, against: backgroundColor);
// Create a contrasting shade of the same color.
final shade = Garnish.contrastingShade(Colors.blue);
// Check accessibility compliance.
final isAccessible = Garnish.hasGoodContrast(foreground, background);Most APIs are also available as extensions directly on Color:
final shade = Colors.blue.contrastingShade();
final ratio = Colors.white.contrastRatio(Colors.black); // ~21.0
final ok = foreground.meetsWCAGAA(background);
final hex = Colors.indigo.toHex(); // "3F51B5"
final scheme = backgroundColor.colorScheme(); // Brightness.light / .darkSee docs/ for the full API reference.
A runnable demo lives in example/. It lets you pick a base color
and watch Garnish generate readable text, analyze contrast against white/black,
flag WCAG AA/AAA compliance, and build a harmonious palette in real time.
cd example
flutter create . # first run only — generates the platform runners
flutter runGarnish uses WCAG 2.1 luminance calculations to determine optimal contrast ratios. The core algorithm calculates relative luminance using the sRGB color space formula, then generates contrasting colors that meet accessibility thresholds (4.5:1 for AA, 7:1 for AAA compliance) via a short binary search over blend amounts toward black or white.
| Library | Import | Contents |
|---|---|---|
| Core | package:garnish/garnish.dart |
Garnish, GarnishMath, GarnishColor, GarnishError, and Color extensions |
| Expansion | package:garnish/garnish_expansion.dart |
GarnishColorExpansion — palette expand/contract utilities |
| Guide | What's inside |
|---|---|
| Getting Started | Install, first operation, theming, advanced config |
| Core API | Garnish contrast generation reference |
| GarnishMath | Luminance, contrast ratio, classification, WCAG checks |
| GarnishColor | Blend, average, brightness/luminance, hex conversion |
| Expansion | Palette expand/contract strategies |
| Recipes | Copy-paste Flutter widgets & patterns |
| Error Handling | Null-safety model & GarnishError |
Garnish
contrastingShade(color, {...})→ColorcontrastingColor(color, {required against, ...})→ColorhasGoodContrast(a, b)→bool
GarnishMath
relativeLuminance(color),rgbBrightness(color),brightness(color, {method})contrastRatio(a, b)classify(color, {threshold, method}),colorScheme(color, {method})meetsWCAGAA(a, b)/meetsWCAGAAA(a, b)andratioMeetsWCAGAA(r)/ratioMeetsWCAGAAA(r)
GarnishColor
blend(a, b, {ratio}),averageColor(colors),extractColorComponents(color)adjustBrightness(color, {by}),adjustLuminance(color, {by})toHex(color, {includeAlpha}),fromHex(string)
Color extensions
contrastingShade(),optimized(bg, {targetRatio})classify(...),colorScheme(...),relativeLuminance(),brightness(...)contrastRatio(other),meetsWCAGAA(other),meetsWCAGAAA(other)hsb,adjustBrightness({by}),adjustLuminance({by}),toHex({includeAlpha})recommendedFontWeight({required against, fontWeightRange, debugStatements})
GarnishColorExpansion (expansion library)
expand(colors, {to}),contract(colors, {to}),linearInterpolation(colors, {to})simpleRepeat(colors, {to}),generateVariations(color, {count})selectPrimaryColor(colors),expandToGradientMesh(color, {size, spread}),expandForGradient(colors),contractToSolid(colors)
This is a faithful port, with a few idiomatic adaptations for Dart/Flutter:
- Non-nullable returns. In Swift many functions return optionals because
UIColor/NSColorcomponent extraction can fail. Flutter'sColoralways exposes its channels, so the math and generation functions return non-nullable values. OnlyGarnishColor.fromHex(parsing can fail) returnsColor?. - Top-level enums.
ContrastDirection,BlendStyle,BrightnessMethod, andColorClassificationare top-level (not nested inside their classes). ColorScheme→Brightness. SwiftUI'sColorSchememaps to Flutter'sBrightnessenum.- No overloads. Dart lacks method overloading, so the ratio-based checks
are named
ratioMeetsWCAGAA/ratioMeetsWCAGAAA. - Parameter naming.
using method:→method:,against:is a named argument,by:is used for brightness/luminance adjustments.
Garnish for Flutter is a port of the original SwiftUI Garnish package created by Aether (@Aeastr).
All credit for the original design, algorithms, documentation, and API goes to the original author. This project simply adapts those ideas to Flutter/Dart. If you find Garnish useful, please ⭐ and support the original repository.
Contributions are welcome. See CONTRIBUTING.md for guidelines.
MIT — see LICENSE. The original Swift package is also MIT licensed, © Aether.