⚡ Node.jsFrontend / Design
Color Validation in Node.js
Validate and normalise color values in Node.js — HEX (#RGB, #RRGGBB, #RRGGBBAA), RGB, RGBA, HSL, HSLA, and CSS named colors. Ideal for design system APIs, theme builders, and brand palette validation.
Also available in Python
Contents
1. Color formats supported
| Format | Example | Alpha? |
|---|---|---|
| #RGB (shorthand) | #F0F | — |
| #RRGGBB | #FF5733 | — |
| #RRGGBBAA | #FF5733CC | ✓ |
| rgb() | rgb(255, 87, 51) | — |
| rgba() | rgba(255, 87, 51, 0.8) | ✓ |
| hsl() | hsl(11, 100%, 60%) | — |
| hsla() | hsla(11, 100%, 60%, 0.8) | ✓ |
| CSS named | red, tomato, cornflowerblue | — |
2. API response structure
Endpoint: GET /v0/color?value=…
{ "valid": true, "format": "hex", "hex": "#FF5733", "rgb": { "r": 255, "g": 87, "b": 51 }, "hsl": { "h": 11, "s": 100, "l": 60 }, "hasAlpha": false, "name": "Orange Red" }
{ "valid": true, "format": "rgba", "hex": "#FF5733CC", "rgb": { "r": 255, "g": 87, "b": 51, "a": 0.8 }, "hsl": { "h": 11, "s": 100, "l": 60, "a": 0.8 }, "hasAlpha": true, "name": null }
- Check
valid - Use
hexas the canonical storage format - Check
hasAlphato gate alpha-unsupported contexts - Use
namefor human-readable display (null if not a named color)
3. Normalising colors to HEX
Accept any color format from users, normalise to #RRGGBB for storage and consistent comparison:
// All of these normalise to the same hex value const inputs = [ '#FF5733', 'rgb(255, 87, 51)', 'hsl(11, 100%, 60%)', 'tomato', // close CSS named color ] const results = await Promise.all(inputs.map(c => iv.color(c))) results.forEach(r => console.log(r.hex)) // → #FF5733 (or close approximation for named colors)
💡Always store the canonical
hex value in your database, not the user-supplied string. This enables consistent equality checks and CSS variable generation.4. Palette validation with Promise.all
import { createClient } from '@isvalid-dev/sdk' const iv = createClient({ apiKey: process.env.ISVALID_API_KEY! }) // Validate any color format and normalise to hex async function normaliseColor(input: string): Promise<string> { const result = await iv.color(input) if (!result.valid) throw new Error(`Invalid color: ${input}`) return result.hex // always returns #RRGGBB or #RRGGBBAA } // Validate a brand palette async function validatePalette(colors: Record<string, string>) { const entries = Object.entries(colors) const results = await Promise.allSettled( entries.map(([, value]) => iv.color(value)) ) const errors: Record<string, string> = {} const normalised: Record<string, string> = {} entries.forEach(([name, raw], i) => { const r = results[i] if (r.status === 'fulfilled' && r.value.valid) { normalised[name] = r.value.hex } else { errors[name] = `Invalid color value: ${raw}` } }) return { valid: Object.keys(errors).length === 0, normalised, errors } } // Example — theme palette validation const palette = await validatePalette({ primary: '#1D4ED8', secondary: 'rgb(99, 102, 241)', accent: 'hsl(262, 83%, 58%)', background: 'white', danger: 'rgba(239, 68, 68, 0.9)', }) console.log(palette.normalised) // { // primary: '#1D4ED8', // secondary: '#6366F1', // accent: '#7C3AED', // background: '#FFFFFF', // danger: '#EF4444E6', // }
5. Edge cases
Shorthand hex expansion
// #F0F expands to #FF00FF — the API returns the full form const result = await iv.color('#F0F') console.log(result.hex) // "#FF00FF"
Blocking alpha in opaque-only contexts
⚠️Some design systems or PDF renderers don't support alpha channels. Check
hasAlpha before accepting the color.const result = await iv.color(userInput) if (result.valid && result.hasAlpha) { throw new Error('Alpha transparency is not supported in this context') }
HSL value ranges
// Hue: 0–360, Saturation: 0–100%, Lightness: 0–100% // These are invalid: await iv.color('hsl(400, 100%, 50%)') // hue > 360 await iv.color('hsl(0, 150%, 50%)') // saturation > 100% await iv.color('rgb(300, 0, 0)') // R value > 255
6. Summary checklist
✓Accept any color format — validate and normalise
✓Store hex (#RRGGBB or #RRGGBBAA) as canonical form
✓Check hasAlpha for opaque-only contexts
✓Expand #RGB shorthand via API response
✓Validate brand palettes in parallel with Promise.all
✓Use name field for human-readable color display
✓Reject HSL/RGB values outside valid ranges
✓Return 422 with field-level errors on invalid colors