[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Type](https://evolu.dev/docs/api-reference/common/Type) › Hex

```ts
const Hex: brand(
  "Hex",
  String,
  (value: string) =>
    value.length % 2 === 0 && /^[0-9a-f]*$/u.test(value)
      ? ok()
      : err<HexError>({ type: "Hex", value }),
  formatHexError,
);
```

Defined in: [packages/common/src/Type.ts:8938](https://github.com/evoluhq/evolu/blob/bc4578a260dd15d5bbf94b83765ca05984d194cb/packages/common/src/Type.ts#L8938)

Lowercase hexadecimal text of whole bytes.

Every byte is two digits, so the length is even, and length constraints count
characters, two per byte. An empty string encodes no bytes. Uppercase digits,
prefixes such as `0x`, and whitespace are rejected so that equal bytes are
equal strings; lowercase text from other sources before validating it.

Convert bytes to Hex with [uint8ArrayToHex](https://evolu.dev/docs/api-reference/common/Type/functions/uint8ArrayToHex) and convert Hex to bytes
with [hexToUint8Array](https://evolu.dev/docs/api-reference/common/Type/functions/hexToUint8Array). The `bytesToHex` and `hexToBytes` functions
convert the same text without a brand, and `hexToBytes` throws on invalid
text instead of returning an error.

### Example

```ts
import { assertErr, assertOk, Hex } from "@evolu/common";

assertOk(Hex.fromUnknown("deadbeef"), "deadbeef");
assertOk(Hex.fromUnknown(""), "");
assertErr(Hex.fromUnknown("DEADBEEF"));
assertErr(Hex.fromUnknown("abc"));
assertErr(Hex.fromUnknown("0xff"));
```