Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→color-shorthand-hex-to-six-digitnext

color-shorthand-hex-to-six-digit5.2.4

Convert shorthand hex color codes into full

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • PURPOSE
  • API — CONV()
  • STRING CONVER…
  • ARRAYS AND PL…
  • PASS-THROUGH…
  • API — TYPES
  • BUILD-PIPELIN…
  • API — VERSION
  • Changelog

No 3rd party dependencies. All dependencies and devDependencies, checked recursively, are Codsen packages.

Permalink to InstallationInstallation

Permalink to Quick TakeQuick Take

Permalink to ExamplesExamples

  • Preserve CSS references and selectors
  • Nested arrays and objects
  • Pass through unsupported input values

Purpose

color-shorthand-hex-to-six-digit expands three-digit hexadecimal colours in strings. It can also process strings inside nested arrays and plain objects without mutating the input graph.

For example, <td bgcolor="#ccc"> becomes <td bgcolor="#cccccc">. Expanding shorthand can be useful in email build pipelines and other systems where explicit six-digit colours are easier to inspect or compare.

API — conv()

The main function conv() is imported like this:

export type Converted<Input> = Input extends string
  ? string
  : Input extends (...arguments_: never[]) => unknown
    ? Input
    : Input extends abstract new (...arguments_: never[]) => unknown
      ? Input
      : Input extends readonly unknown[]
        ? { [Key in keyof Input]: Converted<Input[Key]> }
        : Input extends object
          ? { [Key in keyof Input]: Converted<Input[Key]> }
          : Input;

declare function conv(): undefined;
declare function conv<Input>(input: Input): Converted<Input>;
InputReturn value
String
StringA converted string.
Array or plain object
Array or plain objectA new recursively converted container graph.
Any other value
Any other valueThe original value, returned by identity.
No argument
No argumentundefined.

String conversion

Three-digit colours expand to six digits. Supported four-, six-, and eight-digit forms retain their length and are normalised to lowercase:

import { conv } from "color-shorthand-hex-to-six-digit";

console.log(conv("color: #AbC; border-color: #AaBbCc;"));
// => "color: #aabbcc; border-color: #aabbcc;"

console.log(conv("#AbC8 #AaBbCcDd"));
// => "#abc8 #aabbccdd"

Other hexadecimal lengths are left unchanged.

Selectors and resource fragments

The converter distinguishes colours from common CSS ID selectors and resource references. Complete ID-selector preludes are preserved, as are fragments inside CSS url() and src() functions and HTML href and xlink:href attributes:

console.log(conv("#abc, :not(#def) { color: #abc; }"));
// => "#abc, :not(#def) { color: #aabbcc; }"

console.log(conv('svg { fill: url("icons.svg#abc"); }'));
// => 'svg { fill: url("icons.svg#abc"); }'

console.log(conv('<use xlink:href="icons.svg#abc">'));
// => '<use xlink:href="icons.svg#abc">'

This context handling is deliberately focused; it is not a complete CSS or HTML parser. An ambiguous standalone value such as #abc is treated as a colour and expands to #aabbcc. Use a format-specific parser first when every hash must be classified from full document syntax.

Arrays and plain objects

Arrays and plain objects are copied recursively. Repeated references remain shared in the result, cycles point to the corresponding result container, and sparse arrays retain their holes:

const swatch = { colour: "#abc" };
const input = { first: swatch, second: swatch };
input.self = input;

const result = conv(input);

console.log(result.first.colour);
// => "#aabbcc"

console.log(result.first === result.second);
// => true

console.log(result.self === result);
// => true

console.log(input.first.colour);
// => "#abc"

Ordinary objects retain Object.prototype; null-prototype dictionaries retain a null prototype. Own enumerable string and symbol properties are copied. The string key __proto__ remains an ordinary own data property and cannot change the result’s prototype. Non-enumerable properties are not copied.

Pass-through values and errors

Values that are not strings, arrays, or plain objects pass through unchanged. This includes numbers, booleans, null, undefined, functions, dates, maps, sets, and class instances.

The function does not hide errors raised by user code. Reading an enumerable accessor or traversing a proxy can invoke its getter or trap, and any resulting error propagates. Traversal is recursive, so exceptionally deep container nesting can exceed the JavaScript call-stack limit.

API — types

The package exports Converted<Input>, the recursive conditional return type shown above. String properties widen to string; nested arrays and object properties retain their structural types. Functions, constructors, and other pass-through values keep their input type.

import { type Converted, conv } from "color-shorthand-hex-to-six-digit";

const result = conv({ colour: "#abc", count: 1 as const });
// result: { colour: string; count: 1 }

type ConvertedTheme = Converted<{
  primary: "#abc";
  nested: readonly ["#def", 1];
}>;
// { primary: string; nested: readonly [string, 1] }

Build-pipeline example

Apply conv() after parsing variables or configuration data and before serialising the result:

import { conv } from "color-shorthand-hex-to-six-digit";

const parsedVariables = {
  accent: "#f0c",
  neutral: "#ccc",
  spacing: "8px",
};

const normalisedVariables = conv(parsedVariables);

console.log(normalisedVariables);
// => { accent: "#ff00cc", neutral: "#cccccc", spacing: "8px" }

API — version

You can import version:

Permalink to changelogChangelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab