typescript 45 lines · 9 steps

Lightening and darkening hex colors in TypeScript

A small color toolkit parses hex strings into RGB, shifts each channel, and formats the result back to hex.

Explained by highlit
1type RGB = { r: number; g: number; b: number };
2 
3function parseHex(hex: string): RGB {
4 const normalized = hex.replace(/^#/, "").trim();
5 const expanded =
6 normalized.length === 3
7 ? normalized.split("").map((c) => c + c).join("")
8 : normalized;
9 
10 if (!/^[0-9a-fA-F]{6}$/.test(expanded)) {
11 throw new Error(`Invalid hex color: ${hex}`);
12 }
13 
14 const value = parseInt(expanded, 16);
15 return {
16 r: (value >> 16) & 0xff,
17 g: (value >> 8) & 0xff,
18 b: value & 0xff,
19 };
20}
21 
22function toHex({ r, g, b }: RGB): string {
23 const channel = (n: number) =>
24 Math.round(clamp(n, 0, 255)).toString(16).padStart(2, "0");
25 return `#${channel(r)}${channel(g)}${channel(b)}`;
26}
27 
28function clamp(n: number, min: number, max: number): number {
29 return Math.min(max, Math.max(min, n));
30}
31 
32function adjust(hex: string, amount: number): string {
33 const { r, g, b } = parseHex(hex);
34 const shift = (channel: number) =>
35 amount >= 0
36 ? channel + (255 - channel) * amount
37 : channel * (1 + amount);
38 
39 return toHex({ r: shift(r), g: shift(g), b: shift(b) });
40}
41 
42const lighten = (hex: string, ratio: number) => adjust(hex, Math.abs(ratio));
43const darken = (hex: string, ratio: number) => adjust(hex, -Math.abs(ratio));
44 
45export { parseHex, toHex, lighten, darken };
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Bit-shifting and masking cleanly slice a packed integer into separate byte channels.
  2. 2Validating input with a regex before parsing turns malformed data into a clear error instead of silent garbage.
  3. 3A single core function can spawn readable specializations by fixing the sign of one argument.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Lightening and darkening hex colors in TypeScript — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code