20 KiB
title, description
| title | description |
|---|---|
| Definition Schema Reference | 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. 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
{
"$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.
{
"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.
{
"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.
{
"type": "element",
"name": "circle",
"attributes": {
"cx": "50",
"cy": "50",
"r": "40",
"fill": { "type": "color", "name": "skin" }
},
"children": []
}
Only
whitelisted SVG elements
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
below).
text: text content
Renders raw text inside an SVG element. Supports variable references.
{
"type": "text",
"value": "Hello"
}
Or with a variable:
{
"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).
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.
{
"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:
{
"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:
{
"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 (localurl(#id)is fine) expression(...),behavior:,-moz-bindingjavascript:andvbscript: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.
{
"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 |
scale |
object | Optional. Scale range around the component's center, see Ranges |
translate |
object | Optional. { x?: Range, y?: Range } offsets as a percentage of the component's own width / height, see 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:
{ "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.
{
"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
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.
{
"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
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:
{
"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) |
{
"type": "text",
"value": { "type": "variable", "name": "initials" }
}
{
"attributes": {
"font-family": { "type": "variable", "name": "fontFamily" },
"font-weight": { "type": "variable", "name": "fontWeight" }
}
}
attributes
Global SVG presentation attributes applied to the root <svg> element.
{
"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
for the complete whitelist.
Two attributes have notable extra rules:
hrefaccepts only local fragment refs (#id) and embedded raster images encoded asdata:image/{png|gif|jpeg|webp|avif};base64,…. Remote URLs (http(s)://…) and<script>/xlink:hrefpatterns are rejected.styleis sanitized as a CSS string: the stricter<style>-element ruleset applies (see The<style>element).
Example: minimal style definition
A complete but minimal definition that renders a colored circle:
{
"$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 and
ship two files (both JSON Schema draft-07):
definition.json: validates style definitionsoptions.json: validates the user options passed toAvatar
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 on npm,
dicebear/styles on
Packagist, dicebear-styles on
PyPI, dicebear-styles on
crates.io,
github.com/dicebear/styles/v10
as a Go module and dicebear_styles
on pub.dev.