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
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 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.
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).
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 (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.
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 |
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:
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 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 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 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:
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 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 |
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.jsonThe vendored style definitions shipped by DiceBear live in a separate package: @dicebear/styles on npm and dicebear/styles on Packagist.