hex-rgb
hex-rgb is a single-purpose ES module that converts three-, four-, six-, or eight-digit hexadecimal colors into an RGBA object, an RGBA tuple, or a modern CSS rgb() string. A leading hash is optional, shorthand digits are expanded, and embedded alpha bytes are converted to a 0-to-1 number. You can also override alpha explicitly. It has no runtime dependencies and includes format-sensitive TypeScript overloads, but it is a converter rather than a general color parser, formatter, mixer, or color-space toolkit.
hex-rgb is a clean, dependency-free answer for one narrow conversion in an ESM project. Skip it for CommonJS, untrusted alpha overrides, broader CSS parsing, or any color work that will grow beyond extracting four channels.
Use it if
- You receive strictly hexadecimal colors and need red, green, blue, and alpha channels with a tiny focused API
- You want one call to emit either a typed object, an RGBA tuple, or CSS Color 4 space-separated rgb() syntax
- Your codebase is ESM and accepts a Node 12-or-newer package contract or uses a bundler that understands package exports
- You need four- and eight-digit hex alpha support and want an explicit alpha override to take precedence
- You use CommonJS require: version 5 is ESM-only and exports one index.js module with no require condition
- You need to parse rgb(), hsl(), named colors, 0x-prefixed integers, surrounding whitespace, or any color syntax beyond exactly 3, 4, 6, or 8 hex digits
- You need alpha validation or clamping: although the README says alpha must be from 0 to 1, the implementation accepts any number and can emit values such as 200% or -50%
- You need conversions, interpolation, contrast, gamut mapping, or color manipulation across several spaces; a full color library such as culori fits those jobs better
- You require an actively maintained direct dependency: 5.0.0 was published in May 2021 and the last repository push was in July 2022
Setup reality
npm install hex-rgb adds no runtime dependencies, native code, peer requirements, credentials, generated files, or configuration. Version 5.0.0 declares type: module and exports only ./index.js, so use import hexRgb from 'hex-rgb'. A plain require('hex-rgb') in CommonJS is not supported; either move that caller to ESM, use dynamic import, or choose another converter. The accepted input is deliberately narrow: a string containing exactly 3, 4, 6, or 8 hexadecimal digits, optionally prefixed with one #. Whitespace, CSS color functions, names, and 0x prefixes throw a synchronous TypeError. Four and eight digits treat the final nibble or byte as alpha. The default result is {red, green, blue, alpha}; format: 'array' returns a four-item tuple, and format: 'css' returns modern space-separated rgb() text, with alpha represented as a percentage rounded to two decimal places. That CSS form may not match old consumers expecting comma-separated rgba(). An explicit numeric alpha replaces embedded alpha, but the implementation does not enforce the documented 0-to-1 range, reject NaN, or clamp values. Validate alpha before calling if it can come from users or data files. The bundled declaration file has overloads that narrow results for literal format values, but a format held in a wider union may need application-side narrowing. Errors are immediate, not Promise rejections, and there is no tolerant mode for batch input.
Patterns
Convert a standard hex color to an objectconvert-six-digit-hex
import hexRgb from 'hex-rgb';
const color = hexRgb('#4183c4');
// {red: 65, green: 131, blue: 196, alpha: 1}The leading # is optional. The default return value always includes alpha, even when the input has no alpha component.
Convert three-digit shorthandexpand-short-hex
const white = hexRgb('#fff');
// {red: 255, green: 255, blue: 255, alpha: 1}Each shorthand digit is duplicated, so #fff is interpreted as #ffffff.
Extract alpha from eight-digit hexread-eight-digit-alpha
const color = hexRgb('#4183c488');
console.log(color.alpha);
// 0.5333333333333333The final byte is divided by 255. Object and array formats preserve the full floating-point value rather than rounding it.
Expand shorthand with alpharead-four-digit-alpha
const translucentBlack = hexRgb('#0008');
// {red: 0, green: 0, blue: 0, alpha: 0.5333333333333333}The fourth nibble is duplicated to form the alpha byte, so 8 becomes 88 rather than exactly 50 percent opacity.
Return an array for numeric APIsreturn-rgba-tuple
const rgba = hexRgb('#cd2222cc', {format: 'array'});
// [205, 34, 34, 0.8]With a literal array format, TypeScript returns the RgbaTuple type in red, green, blue, alpha order.
Generate a modern CSS rgb() stringreturn-css-color
const cssColor = hexRgb('#4183c488', {format: 'css'});
// 'rgb(65 131 196 / 53.33%)'The function uses modern space-separated syntax and rounds the alpha percentage to two decimal places.
Generate CSS for an opaque coloromit-opaque-css-alpha
const cssColor = hexRgb('#000f', {format: 'css'});
// 'rgb(0 0 0)'When alpha is exactly 1, CSS output omits the slash and alpha value instead of emitting 100%.
Replace embedded alpha explicitlyoverride-alpha-channel
const color = hexRgb('#22222299', {alpha: 1});
// {red: 34, green: 34, blue: 34, alpha: 1}The option wins over the 99 suffix. Validate that external alpha is finite and between 0 and 1 before calling.
Guard an untrusted alpha valuevalidate-alpha-override
function convertWithAlpha(hex: string, alpha: number) {
if (!Number.isFinite(alpha) || alpha < 0 || alpha > 1)
throw new RangeError('alpha must be between 0 and 1');
return hexRgb(hex, {alpha});
}hex-rgb documents the range but does not enforce it. Without this guard, CSS format can emit negative percentages or values above 100%.
Report invalid input without crashing a batchhandle-invalid-hex
function tryHex(hex: unknown) {
try {
return {ok: true, value: hexRgb(hex as string)};
} catch (error) {
if (error instanceof TypeError)
return {ok: false, error: error.message};
throw error;
}
}Invalid type, characters, or length throw synchronously with Expected a valid hex string; the package has no silent or nullable mode.
Load the ESM package from CommonJSload-from-commonjs
async function convert(hex) {
const {default: hexRgb} = await import('hex-rgb');
return hexRgb(hex);
}
convert('#fff').then(console.log);Version 5 cannot be loaded with require. Dynamic import is the compatibility escape hatch for a CommonJS caller and makes the call path asynchronous.
Convert a palette to typed channel objectsmap-a-color-palette
const palette = ['#0f172a', '#38bdf8', '#f8fafc'];
const channels = palette.map(hex => ({hex, ...hexRgb(hex)}));One invalid color throws and stops map. Use an explicit loop with try/catch when partial results are acceptable.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| color-convert | npm | Choose it when you need conversions among many color models rather than only hexadecimal to RGB |
| polished | npm | Choose it in styling code that also needs readable color helpers, mixing, lightening, contrast, and other CSS utilities |
| culori | npm | Choose it for parsing, converting, interpolating, comparing, and mapping colors across modern color spaces |