Files
dicebear--dicebear/apps/docs/pages/specification/definition-schema/index.md
T
2026-07-13 12:25:08 +08:00

582 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.