Quick Start
This guide shows how to create and validate your first PaletteJSON file.
Minimal file
A minimal valid file contains at least one palette, with a name, slug, type, and two or more colours.
- Bare Minimum
{
"palettes": [
{
"name": "Example",
"slug": "example",
"type": "categorical",
"colors": [{ "hex": "#FFFFFF" }, { "hex": "#000000" }]
}
]
}
- name — human-readable label for the palette.
- slug — URL-safe identifier (lowercase letters, numbers, hyphens).
- type — one of
categorical
,sequential
,diverging
. - colors — array with at least two colours.
Colour values
Each colour can be defined with hex
(#RRGGBB
or #RRGGBBAA
) or components
(numeric array interpreted by a palette-level colorSpace
).
If both are present, consumers should treat components
as authoritative and use hex
for preview/interoperability.
File identification
To make your file portable:
- Extension:
.palette.json
- Encoding: UTF-8
- Media type:
application/prs.palettejson+json
(fall back toapplication/json
if needed) - Apple UTI (optional):
org.palettejson.json
.
note
These identifiers are recommendations for tooling and do not affect schema validity.
Validating a file
You can validate PaletteJSON against the official schema (palettejson.schema.json
), which targets JSON Schema draft 2020-12.
- Node.js (AJV v8)
- Python (jsonschema)
// Install: npm i ajv
import Ajv from "ajv";
import addFormats from "ajv-formats";
import schema from "./palettejson.schema.json" assert { type: "json" };
// Example data
const data = {
palettes: [
{
name: "Example",
slug: "example",
type: "categorical",
colors: [{ hex: "#FFFFFF" }, { hex: "#000000" }],
},
],
};
const ajv = new Ajv({ strict: false }); // strict off if you prefer fewer warnings
addFormats(ajv);
const validate = ajv.compile(schema);
const valid = validate(data);
if (valid) {
console.log("Valid!");
} else {
console.error("Validation errors:", validate.errors);
}
# Install: pip install jsonschema
import json
from jsonschema import validate, Draft202012Validator
# Load the schema file (placed next to this script)
with open("palettejson.schema.json", "r", encoding="utf-8") as f:
schema = json.load(f)
# Example data
data = {
"palettes": [
{
"name": "Example",
"slug": "example",
"type": "categorical",
"colors": [{"hex": "#FFFFFF"}, {"hex": "#000000"}]
}
]
}
# Optional: sanity-check the schema itself
Draft202012Validator.check_schema(schema)
# Validate
validate(instance=data, schema=schema)
print("Valid!")
Common gotchas (v0.1)
- If any colour in a palette uses
components
, the palette must declarecolorSpace
. - If any colour has a
position
, all colours in that palette must have aposition
(1-based). hex
is always interpreted as display sRGB; alpha (if present) is the last pair:#RRGGBBAA
.- Component ranges depend on
colorSpace
:sRGB
/DisplayP3
: 3–4 numbers, each in [0, 1]sRGB-linear-extended
: either 3 numbers (unbounded) or 4 with alpha in [0, 1]Lab
: exactly 3 numbers; L in [0, 100] (a/b unbounded)OKLCH
: exactly 3 numbers; L in [0, 1], C ≥ 0, h ∈ [0, 360)
Next steps
- Read the File Format and Palette specs for required/optional fields.
- See the Colour page for
hex
vscomponents
,references
,position
, and legibility metadata. - Explore Examples for richer use cases.