582 lines
20 KiB
Markdown
582 lines
20 KiB
Markdown
---
|
||
title: Definition Schema Reference
|
||
description: >
|
||
Complete reference for the DiceBear avatar style definition schema. Learn how
|
||
style definitions are structured with canvas, components, colors, and
|
||
metadata.
|
||
---
|
||
|
||
# Definition schema reference
|
||
|
||
Every DiceBear avatar style is a JSON file that follows the
|
||
[DiceBear Definition Schema](https://github.com/dicebear/schema). This page
|
||
documents the complete structure of a style definition.
|
||
|
||
## Overview
|
||
|
||
A style definition describes everything needed to generate an avatar: the canvas
|
||
size, the SVG elements to render, the components that can be randomized, and the
|
||
color palettes available. The definition is purely declarative: no code, no
|
||
functions. The rendering logic lives in the DiceBear Core implementation.
|
||
|
||
## Top-level structure
|
||
|
||
```json
|
||
{
|
||
"$schema": "https://...",
|
||
"$id": "https://...",
|
||
"$comment": "Optional comment",
|
||
"meta": { ... },
|
||
"canvas": { ... },
|
||
"components": { ... },
|
||
"colors": { ... },
|
||
"attributes": { ... }
|
||
}
|
||
```
|
||
|
||
| Property | Required | Description |
|
||
| ------------ | -------- | ------------------------------------------------------------------------------------------- |
|
||
| `$schema` | No | URL to the definition schema for editor validation |
|
||
| `$id` | No | Canonical identifier for this definition (typically the URL it is hosted at, max 256 chars) |
|
||
| `$comment` | No | Free-text comment, e.g. "Generated by Figma" (max 4096 chars) |
|
||
| `meta` | No | License, creator, and source metadata |
|
||
| `canvas` | **Yes** | Canvas dimensions and root element tree |
|
||
| `components` | No | Named, randomizable SVG components (up to 512 entries) |
|
||
| `colors` | No | Named color palettes for dynamic coloring (up to 512 entries) |
|
||
| `attributes` | No | Global SVG attributes for the root `<svg>` element |
|
||
|
||
## `meta`
|
||
|
||
Metadata about the style, used in license comments, the CLI banner, and the
|
||
documentation.
|
||
|
||
```json
|
||
{
|
||
"meta": {
|
||
"license": {
|
||
"name": "CC0 1.0",
|
||
"url": "https://creativecommons.org/publicdomain/zero/1.0/",
|
||
"text": "Full license text..."
|
||
},
|
||
"creator": {
|
||
"name": "DiceBear",
|
||
"url": "https://www.dicebear.com"
|
||
},
|
||
"source": {
|
||
"name": "Initials",
|
||
"url": "https://github.com/dicebear/dicebear"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## `canvas`
|
||
|
||
Defines the SVG viewport and the root element tree. The `width` and `height`
|
||
determine the `viewBox` of the generated SVG.
|
||
|
||
```json
|
||
{
|
||
"canvas": {
|
||
"width": 100,
|
||
"height": 100,
|
||
"elements": [
|
||
{ "type": "component", "name": "background" },
|
||
{ "type": "component", "name": "face" }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
| Property | Type | Required | Description |
|
||
| ---------- | ------ | -------- | ------------------------------------------------ |
|
||
| `width` | number | **Yes** | Canvas width in pixels (>= 1) |
|
||
| `height` | number | **Yes** | Canvas height in pixels (>= 1) |
|
||
| `elements` | array | **Yes** | Root element tree (up to 1024 top-level entries) |
|
||
|
||
## Elements
|
||
|
||
Elements are the building blocks of the SVG. Three types are supported:
|
||
|
||
### `element`: SVG tag
|
||
|
||
Renders an SVG element like `<circle>`, `<path>`, `<g>`, etc.
|
||
|
||
```json
|
||
{
|
||
"type": "element",
|
||
"name": "circle",
|
||
"attributes": {
|
||
"cx": "50",
|
||
"cy": "50",
|
||
"r": "40",
|
||
"fill": { "type": "color", "name": "skin" }
|
||
},
|
||
"children": []
|
||
}
|
||
```
|
||
|
||
Only
|
||
[whitelisted SVG elements](https://github.com/dicebear/schema/blob/main/src/definition.json)
|
||
are allowed (e.g. `circle`, `path`, `g`, `rect`, `text`, `defs`, `filter`,
|
||
`linearGradient`, `radialGradient`, etc.). Elements like `script`,
|
||
`foreignObject`, and `a` are blocked for security.
|
||
|
||
A node may have at most 1024 children. The element with `name: "defs"` has
|
||
special semantics (see [Reusable `<defs>` entries](#reusable-defs-entries)
|
||
below).
|
||
|
||
### `text`: text content
|
||
|
||
Renders raw text inside an SVG element. Supports variable references.
|
||
|
||
```json
|
||
{
|
||
"type": "text",
|
||
"value": "Hello"
|
||
}
|
||
```
|
||
|
||
Or with a variable:
|
||
|
||
```json
|
||
{
|
||
"type": "text",
|
||
"value": { "type": "variable", "name": "initials" }
|
||
}
|
||
```
|
||
|
||
Only `initial` and `initials` are accepted in a text `value`. Other variables
|
||
(`fontFamily`, `fontWeight`) are only valid in their dedicated attributes (see
|
||
[Variable references](#variable-references)).
|
||
|
||
### `component`: component reference
|
||
|
||
References a named component defined in the `components` section. The DiceBear
|
||
Core will select a variant based on the seed and options.
|
||
|
||
```json
|
||
{
|
||
"type": "component",
|
||
"name": "eyes"
|
||
}
|
||
```
|
||
|
||
A component reference can carry its own `attributes` map. They are written
|
||
verbatim onto the emitted `<use>` element, which is how you place an instance of
|
||
a component on the canvas:
|
||
|
||
```json
|
||
{
|
||
"type": "component",
|
||
"name": "eyes",
|
||
"attributes": {
|
||
"transform": "translate(10 20)"
|
||
}
|
||
}
|
||
```
|
||
|
||
A user-supplied `transform` is prepended to the per-component
|
||
rotate/translate/scale picked by the renderer, so it acts as the outer
|
||
(placement) transform.
|
||
|
||
### The `<style>` element
|
||
|
||
`<style>` is supported but is a special case. Its CSS body must be supplied as
|
||
one or more `text` children, not as a single string and not via `children`
|
||
holding generic elements:
|
||
|
||
```json
|
||
{
|
||
"type": "element",
|
||
"name": "style",
|
||
"children": [
|
||
{
|
||
"type": "text",
|
||
"value": ".dark { fill: #000; }"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
A `<style>` element may hold at most 64 text children. The CSS body is sanitized
|
||
more strictly than ordinary attribute values:
|
||
|
||
- Known-dangerous `@`-rules (`@import`, `@font-face`, `@document`, `@charset`)
|
||
are rejected. Other at-rules (`@media`, `@keyframes`, `@supports`, `@layer`,
|
||
…) are permitted, but their contents are still passed through the common
|
||
filter described below.
|
||
|
||
The following are rejected in every CSS body **and every attribute value** (the
|
||
shared `filteredString` injection filter):
|
||
|
||
- External `url(...)` references (local `url(#id)` is fine)
|
||
- `expression(...)`, `behavior:`, `-moz-binding`
|
||
- `javascript:` and `vbscript:` URI schemes
|
||
- Backslash escape sequences
|
||
|
||
This is a defense-in-depth filter, not a CSS validator: substring matches reject
|
||
otherwise-harmless strings that happen to contain a blocked token (e.g. the
|
||
literal word `javascript:` in plain text).
|
||
|
||
### Reusable `<defs>` entries
|
||
|
||
`<defs>` is whitelisted as an ordinary element, but the renderer treats it
|
||
specially: every child of an element named `defs`, anywhere in the tree, is
|
||
hoisted into the document-wide `<defs>` block alongside generated gradients,
|
||
clip paths, and component bodies. This keeps the rendered SVG to a single
|
||
`<defs>` element while letting style authors ship reusable fragments (filters,
|
||
gradients, masks, …) and reference them from elsewhere in the tree.
|
||
|
||
## `components`
|
||
|
||
Named, randomizable parts of the avatar. Each component defines a set of
|
||
variants that the PRNG can choose from.
|
||
|
||
```json
|
||
{
|
||
"components": {
|
||
"eyes": {
|
||
"width": 80,
|
||
"height": 40,
|
||
"probability": 100,
|
||
"rotate": { "min": -10, "max": 10 },
|
||
"scale": { "min": 0.9, "max": 1.1 },
|
||
"translate": {
|
||
"x": { "min": 0, "max": 0 },
|
||
"y": { "min": -5, "max": 5 }
|
||
},
|
||
"variants": {
|
||
"happy": {
|
||
"weight": 1,
|
||
"elements": [...]
|
||
},
|
||
"surprised": {
|
||
"weight": 1,
|
||
"elements": [...]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
| Property | Type | Description |
|
||
| ------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
|
||
| `width` | number | **Required.** Component canvas width in pixels (>= 1) |
|
||
| `height` | number | **Required.** Component canvas height in pixels (>= 1) |
|
||
| `probability` | number | Optional. Chance the component appears, 0 to 100 (default `100`) |
|
||
| `rotate` | object | Optional. Rotation range, see [Ranges](#ranges) |
|
||
| `scale` | object | Optional. Scale range around the component's center, see [Ranges](#ranges) |
|
||
| `translate` | object | Optional. `{ x?: Range, y?: Range }` offsets as a percentage of the component's own `width` / `height`, see [Ranges](#ranges) |
|
||
| `variants` | object | **Required.** Named variant definitions (up to 512) |
|
||
|
||
`translate.x` and `translate.y` are expressed as percentages of the component's
|
||
own `width` and `height`. A value of `100` shifts the component by its full
|
||
width or height; `0` leaves it in place. The example above
|
||
(`y: { min: -5, max: 5 }`) therefore means "shift the component vertically by up
|
||
to 5 % of its height in either direction".
|
||
|
||
### Ranges
|
||
|
||
`rotate`, `scale`, `translate.x`, and `translate.y` all use the same range
|
||
object:
|
||
|
||
```json
|
||
{ "min": -10, "max": 10, "step": 5 }
|
||
```
|
||
|
||
| Property | Type | Description |
|
||
| -------- | ------ | --------------------------------------------------------------------- |
|
||
| `min` | number | **Required.** Lower bound of the range |
|
||
| `max` | number | **Required.** Upper bound of the range |
|
||
| `step` | number | Optional. Positive value that quantizes the range to `min + i × step` |
|
||
|
||
For a fixed value, set `min === max`. With `step`, the PRNG samples from
|
||
`{ min + i × step | 0 ≤ i ≤ ⌊(max − min) / step⌋ }`, so when `(max − min)` is
|
||
not a multiple of `step`, `max` itself is unreachable. Without `step`, the range
|
||
is continuous.
|
||
|
||
The numeric domains differ per field: `rotate` and the inner `step` values are
|
||
in degrees (-360 to 360, step ≤ 720), `scale` is 0 to 10 (step ≤ 10), and
|
||
`translate.x` / `translate.y` are percentages from -1000 to 1000 (step ≤ 2000).
|
||
|
||
### Component aliases
|
||
|
||
A component can be aliased to another component using `extends`. An alias has no
|
||
dimensions or variants of its own: it inherits everything from the referenced
|
||
component, but renders as an independent, separately-randomized instance. This
|
||
is useful when you want the same visual component to appear twice (e.g. left and
|
||
right earrings) and have each occurrence pick its own variant.
|
||
|
||
```json
|
||
{
|
||
"components": {
|
||
"earring": {
|
||
"width": 20,
|
||
"height": 20,
|
||
"variants": {
|
||
"stud": { "elements": [...] },
|
||
"hoop": { "elements": [...] }
|
||
}
|
||
},
|
||
"earringLeft": { "extends": "earring" },
|
||
"earringRight": { "extends": "earring" }
|
||
}
|
||
}
|
||
```
|
||
|
||
An alias is a strict reference: `extends` is its **only** allowed property. It
|
||
must point to a base component (not another alias) defined in the same
|
||
`components` map. Width, height, probability, rotate, scale, translate, and
|
||
variants are inherited from the source. Aliases do not expose their own
|
||
`${aliasName}Variant` or `${aliasName}Probability` user options. Both are shared
|
||
with the source via `${sourceName}Variant` and `${sourceName}Probability`. The
|
||
renderer still rolls the PRNG independently per alias, so each occurrence picks
|
||
its own variant within the shared constraints. See
|
||
[the implementation guide](/specification/implement-dicebear-core/#component-options)
|
||
for details.
|
||
|
||
### Variants
|
||
|
||
Each variant contains an element tree and an optional weight:
|
||
|
||
| Property | Type | Default | Description |
|
||
| ---------- | ------ | ------- | ------------------------------------------------------------ |
|
||
| `elements` | array | — | **Required.** SVG element tree for this variant (up to 1024) |
|
||
| `weight` | number | `1` | Selection weight for the PRNG (0 to 1,000,000) |
|
||
|
||
Higher weights make a variant more likely to be selected. A weight of `0`
|
||
excludes the variant entirely, unless every variant has weight `0`, in which
|
||
case the PRNG falls back to an unweighted pick across all of them.
|
||
|
||
## `colors`
|
||
|
||
Named color palettes. The PRNG picks a color from the palette based on the seed.
|
||
|
||
```json
|
||
{
|
||
"colors": {
|
||
"skin": {
|
||
"values": ["#f5d6c3", "#d4a889", "#a67c5b", "#614335"]
|
||
},
|
||
"text": {
|
||
"values": ["#ffffff", "#000000"],
|
||
"contrastTo": "skin"
|
||
},
|
||
"hair": {
|
||
"values": ["#2c1b18", "#b58143", "#d6b370", "#724133"],
|
||
"notEqualTo": ["skin"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
| Property | Type | Description |
|
||
| ------------ | -------- | ---------------------------------------------------------------------------------------------- |
|
||
| `values` | string[] | **Required.** Hex colors in `#RGB`, `#RGBA`, `#RRGGBB`, or `#RRGGBBAA` form (1 to 128 entries) |
|
||
| `contrastTo` | string | Optional. Pick the color with highest contrast to this group's selection |
|
||
| `notEqualTo` | string[] | Optional. Filter out colors already picked by these groups (up to 64 refs) |
|
||
|
||
A definition may declare up to 512 color groups.
|
||
|
||
### Color constraints
|
||
|
||
**`contrastTo`** bypasses random selection. Instead, the candidate colors are
|
||
sorted by
|
||
[WCAG 2.1 contrast ratio](https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio)
|
||
against the referenced color, and the highest-contrast color is picked. This is
|
||
useful for ensuring text readability.
|
||
|
||
**`notEqualTo`** filters out colors that were already selected for the
|
||
referenced color groups. This prevents adjacent parts from having the same
|
||
color. Comparison is done on the RGB hex (alpha stripped); if the filter would
|
||
leave the candidate list empty, the renderer falls back to the unfiltered list.
|
||
|
||
The schema does not detect cycles (`a` ⇄ `b` constraints). Renderers resolve
|
||
palettes in definition order and throw at render time when a cycle is detected.
|
||
|
||
## Color references in attributes
|
||
|
||
Color-bearing attributes (`fill`, `stroke`, `stop-color`, `color`,
|
||
`flood-color`, `lighting-color`) accept either a literal CSS color string (named
|
||
color, hex, `rgb()`, `oklch()`, `color-mix()`, a local paint server reference
|
||
like `url(#id)`, …) or a reference to a named palette:
|
||
|
||
```json
|
||
{
|
||
"fill": { "type": "color", "name": "skin" }
|
||
}
|
||
```
|
||
|
||
A palette reference is resolved at render time to the color the PRNG picked for
|
||
the `skin` group. Literal strings are not validated as CSS (invalid syntax is
|
||
the browser's problem), but the shared injection filter still applies (no
|
||
`javascript:`, no external `url(...)`, …).
|
||
|
||
## Variable references
|
||
|
||
A handful of properties accept a `{ "type": "variable", "name": "…" }` object in
|
||
place of a literal string. Each variable is only valid in a specific spot. The
|
||
schema rejects mismatched placements.
|
||
|
||
| Variable | Allowed in | Resolves to |
|
||
| ------------ | ----------------------- | ----------------------------------------------------------- |
|
||
| `initial` | `text` element `value` | First character of the initials derived from the seed |
|
||
| `initials` | `text` element `value` | Full initials (1 to 2 characters) derived from the seed |
|
||
| `fontFamily` | `font-family` attribute | Resolved `fontFamily` user option (defaults to `system-ui`) |
|
||
| `fontWeight` | `font-weight` attribute | Resolved `fontWeight` user option (defaults to `400`) |
|
||
|
||
```json
|
||
{
|
||
"type": "text",
|
||
"value": { "type": "variable", "name": "initials" }
|
||
}
|
||
```
|
||
|
||
```json
|
||
{
|
||
"attributes": {
|
||
"font-family": { "type": "variable", "name": "fontFamily" },
|
||
"font-weight": { "type": "variable", "name": "fontWeight" }
|
||
}
|
||
}
|
||
```
|
||
|
||
## `attributes`
|
||
|
||
Global SVG presentation attributes applied to the root `<svg>` element.
|
||
|
||
```json
|
||
{
|
||
"attributes": {
|
||
"fill": "none",
|
||
"shape-rendering": "auto"
|
||
}
|
||
}
|
||
```
|
||
|
||
Only safe SVG presentation attributes are allowed; event handlers (`onclick`, …)
|
||
and namespaced attributes (`xlink:href`, …) are rejected. See the
|
||
[schema source](https://github.com/dicebear/schema/blob/main/src/definition.json)
|
||
for the complete whitelist.
|
||
|
||
Two attributes have notable extra rules:
|
||
|
||
- **`href`** accepts only local fragment refs (`#id`) and embedded raster images
|
||
encoded as `data:image/{png|gif|jpeg|webp|avif};base64,…`. Remote URLs
|
||
(`http(s)://…`) and `<script>`/`xlink:href` patterns are rejected.
|
||
- **`style`** is sanitized as a CSS string: the stricter `<style>`-element
|
||
ruleset applies (see [The `<style>` element](#the-style-element)).
|
||
|
||
## Example: minimal style definition
|
||
|
||
A complete but minimal definition that renders a colored circle:
|
||
|
||
```json
|
||
{
|
||
"$schema": "https://cdn.hopjs.net/npm/@dicebear/schema@1.0.0/dist/definition.min.json",
|
||
"canvas": {
|
||
"width": 100,
|
||
"height": 100,
|
||
"elements": [
|
||
{
|
||
"type": "element",
|
||
"name": "circle",
|
||
"attributes": {
|
||
"cx": "50",
|
||
"cy": "50",
|
||
"r": "45",
|
||
"fill": { "type": "color", "name": "background" }
|
||
}
|
||
},
|
||
{
|
||
"type": "component",
|
||
"name": "face"
|
||
}
|
||
]
|
||
},
|
||
"components": {
|
||
"face": {
|
||
"width": 100,
|
||
"height": 100,
|
||
"variants": {
|
||
"smile": {
|
||
"elements": [
|
||
{
|
||
"type": "element",
|
||
"name": "path",
|
||
"attributes": {
|
||
"d": "M 30 60 Q 50 80 70 60",
|
||
"stroke": "#000000",
|
||
"stroke-width": "3",
|
||
"fill": "none"
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"neutral": {
|
||
"elements": [
|
||
{
|
||
"type": "element",
|
||
"name": "line",
|
||
"attributes": {
|
||
"x1": "35",
|
||
"y1": "65",
|
||
"x2": "65",
|
||
"y2": "65",
|
||
"stroke": "#000000",
|
||
"stroke-width": "3"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"colors": {
|
||
"background": {
|
||
"values": ["#f9c74f", "#90be6d", "#43aa8b", "#577590", "#f94144"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Schema package
|
||
|
||
The schemas live in [`@dicebear/schema`](https://github.com/dicebear/schema) and
|
||
ship two files (both JSON Schema **draft-07**):
|
||
|
||
- **`definition.json`**: validates style definitions
|
||
- **`options.json`**: validates the user options passed to `Avatar`
|
||
|
||
Install via your package manager:
|
||
|
||
| Ecosystem | Install |
|
||
| --------- | ----------------------------------- |
|
||
| npm | `npm install @dicebear/schema` |
|
||
| Composer | `composer require dicebear/schema` |
|
||
| PyPI | `pip install dicebear-schema` |
|
||
| Cargo | `cargo add dicebear-schema` |
|
||
| Go | `go get github.com/dicebear/schema` |
|
||
| pub.dev | `dart pub add dicebear_schema` |
|
||
|
||
Or reference the schema directly from a CDN, handy for the `$schema` field of
|
||
your style definition so editors like VS Code provide autocomplete and inline
|
||
validation:
|
||
|
||
```
|
||
https://cdn.hopjs.net/npm/@dicebear/schema@1.0.0/dist/definition.min.json
|
||
https://cdn.hopjs.net/npm/@dicebear/schema@1.0.0/dist/options.min.json
|
||
```
|
||
|
||
The vendored style definitions shipped by DiceBear live in a separate package:
|
||
[`@dicebear/styles`](https://www.npmjs.com/package/@dicebear/styles) on npm,
|
||
[`dicebear/styles`](https://packagist.org/packages/dicebear/styles) on
|
||
Packagist, [`dicebear-styles`](https://pypi.org/project/dicebear-styles/) on
|
||
PyPI, [`dicebear-styles`](https://crates.io/crates/dicebear-styles) on
|
||
crates.io,
|
||
[`github.com/dicebear/styles/v10`](https://pkg.go.dev/github.com/dicebear/styles/v10)
|
||
as a Go module and [`dicebear_styles`](https://pub.dev/packages/dicebear_styles)
|
||
on pub.dev.
|