Files
2026-07-13 12:25:08 +08:00

20 KiB
Raw Permalink Blame History

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 (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.

{
  "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 (ab 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:

  • 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).

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 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 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.