Color Utilities

Convert between hex, RGB, and HSL. Lighten, darken, and manipulate colors in pure JavaScript — no library needed.

hexToRgb

Convert a hex color string to an RGB object.

const hexToRgb = (hex) => {
  const clean = hex.replace("#", "");
  const expanded = clean.length === 3
    ? clean.split("").map((c) => c + c).join("")
    : clean;
  const num = parseInt(expanded, 16);
  return {
    r: (num >> 16) & 255,
    g: (num >> 8) & 255,
    b: num & 255,
  };
};

hexToRgb("#ff5733"); // { r: 255, g: 87, b: 51 }
hexToRgb("#fff");    // { r: 255, g: 255, b: 255 }
hexToRgb("#000000"); // { r: 0, g: 0, b: 0 }

rgbToHex

Convert RGB values to a hex color string.

const rgbToHex = (r, g, b) =>
  "#" + [r, g, b].map((v) => v.toString(16).padStart(2, "0")).join("");

rgbToHex(255, 87, 51);   // "#ff5733"
rgbToHex(0, 0, 0);       // "#000000"
rgbToHex(255, 255, 255); // "#ffffff"

hexToHsl

Convert a hex color to HSL values.

const hexToHsl = (hex) => {
  const { r, g, b } = hexToRgb(hex);
  const rr = r / 255, gg = g / 255, bb = b / 255;
  const max = Math.max(rr, gg, bb), min = Math.min(rr, gg, bb);
  let h, s;
  const l = (max + min) / 2;
  if (max === min) {
    h = s = 0;
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case rr: h = ((gg - bb) / d + (gg < bb ? 6 : 0)) / 6; break;
      case gg: h = ((bb - rr) / d + 2) / 6; break;
      case bb: h = ((rr - gg) / d + 4) / 6; break;
    }
  }
  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100),
  };
};

hexToHsl("#ff5733"); // { h: 11, s: 100, l: 60 }
hexToHsl("#3498db"); // { h: 204, s: 70, l: 53 }

hslToHex

Convert HSL values back to a hex string.

const hslToHex = (h, s, l) => {
  s /= 100;
  l /= 100;
  const a = s * Math.min(l, 1 - l);
  const f = (n) => {
    const k = (n + h / 30) % 12;
    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
    return Math.round(255 * color).toString(16).padStart(2, "0");
  };
  return `#${f(0)}${f(8)}${f(4)}`;
};

hslToHex(11, 100, 60);  // "#ff5733"
hslToHex(0, 0, 100);    // "#ffffff"
hslToHex(0, 0, 0);      // "#000000"

lighten

Lighten a hex color by a percentage.

const lighten = (hex, amount) => {
  const { h, s, l } = hexToHsl(hex);
  return hslToHex(h, s, Math.min(100, l + amount));
};

lighten("#3498db", 20); // lighter blue
lighten("#ff5733", 15); // lighter red-orange

darken

Darken a hex color by a percentage.

const darken = (hex, amount) => {
  const { h, s, l } = hexToHsl(hex);
  return hslToHex(h, s, Math.max(0, l - amount));
};

darken("#3498db", 20); // darker blue
darken("#ffffff", 10); // light grey

adjustOpacity

Convert a hex color to rgba() with a custom opacity.

const adjustOpacity = (hex, opacity) => {
  const { r, g, b } = hexToRgb(hex);
  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
};

adjustOpacity("#ff5733", 0.5);  // "rgba(255, 87, 51, 0.5)"
adjustOpacity("#3498db", 0.8);  // "rgba(52, 152, 219, 0.8)"

generateRandomColor

Generate a random hex color.

const randomColor = () =>
  "#" + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, "0");

randomColor(); // "#a3f2c1" (random)
randomColor(); // "#3e7bff" (random)

getContrastColor

Return black or white depending on which has better contrast against a background color.

const getContrastColor = (hex) => {
  const { r, g, b } = hexToRgb(hex);
  // Perceived luminance formula
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  return luminance > 0.5 ? "#000000" : "#ffffff";
};

getContrastColor("#ffffff"); // "#000000" (use black text on white)
getContrastColor("#000000"); // "#ffffff" (use white text on black)
getContrastColor("#3498db"); // "#ffffff" (white text on blue)
getContrastColor("#f0e68c"); // "#000000" (black text on khaki)

isValidHex

Check if a string is a valid hex color.

const isValidHex = (color) =>
  /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(color);

isValidHex("#fff");     // true
isValidHex("#1a2b3c"); // true
isValidHex("ff5733");  // false (missing #)
isValidHex("#12345");  // false (wrong length)

blendColors

Mix two hex colors together at a given ratio.

const blendColors = (hex1, hex2, ratio = 0.5) => {
  const c1 = hexToRgb(hex1);
  const c2 = hexToRgb(hex2);
  const blend = (a, b) => Math.round(a + (b - a) * ratio);
  return rgbToHex(blend(c1.r, c2.r), blend(c1.g, c2.g), blend(c1.b, c2.b));
};

blendColors("#ff0000", "#0000ff");       // "#800080" (purple)
blendColors("#ff0000", "#0000ff", 0.25); // "#bf0040" (more red)

Summary

FunctionPurpose
hexToRgb(hex)"#ff5733"{ r, g, b }
rgbToHex(r, g, b)255, 87, 51"#ff5733"
hexToHsl(hex)"#3498db"{ h, s, l }
hslToHex(h, s, l)204, 70, 53"#3498db"
lighten(hex, %)Make a color lighter
darken(hex, %)Make a color darker
adjustOpacity(hex, n)Hex → rgba(...)
randomColor()Random hex color
getContrastColor(hex)"#000" or "#fff" for readable text
isValidHex(color)Validate hex color string
blendColors(a, b, ratio)Mix two colors