Command Palette

Search for a command to run...

Theme Specification

Complete technical specification for dotLottie dynamic theming

Theme Specification

Dynamic theming enables runtime customization of Lottie animations by overriding animated property values without modifying the original animation file.

Version

Current specification version: 1.0

Overview

Themes are JSON files stored in the t/ directory of a .lottie archive. Each theme file contains an array of rules that override specific animated properties. Rules target properties by their Lottie Slot ID — only properties that have been assigned a slot ID in the Lottie animation can be themed.

Use Cases

  • Light/dark mode switching

  • Brand color customization

  • Accessibility adjustments (high contrast)

  • Seasonal or contextual styling

File Location

Theme files are stored in the t/ directory and referenced from the manifest:

{
  "version": "2",
  "animations": [
    {
      "id": "my_animation",
      "initialTheme": "light",
      "themes": ["light", "dark"]
    }
  ],
  "themes": [
    { "id": "light", "name": "Light Theme" },
    { "id": "dark", "name": "Dark Theme" }
  ]
}

The id values correspond to files in the archive: "light"t/light.json.

Theme File Format

A theme file is a JSON object with a single rules array:

FieldRequiredTypeDescription
rulesYesRule[]List of property overrides. Each entry targets exactly one slotted Lottie property.

Example Theme File

{
  "rules": [
    {
      "id": "background_color",
      "type": "Color",
      "value": [0.12, 0.12, 0.12]
    },
    {
      "id": "icon_opacity",
      "type": "Scalar",
      "value": 80
    },
    {
      "id": "brand_color",
      "type": "Color",
      "animations": ["animation_01"],
      "value": [0.0, 0.48, 1.0]
    }
  ]
}

Rule

A rule targets a specific slotted property in a Lottie animation.

FieldRequiredTypeDescription
idYesStringSlot ID of the property to override. Case-sensitive.
typeYes"Color" | "Scalar" | "Position" | "Vector" | "Gradient" | "Image" | "Text"The rule type, matching the Lottie property type being overridden.
animationsNostring[]Limit the rule to specific animations by ID. If omitted, the rule applies to all animations.
valueYes*See per-type tables belowStatic override value. Required if keyframes is not provided.
keyframesYes*Type-specific Keyframe objectsAnimated override. Required if value is not provided. Takes precedence over value.
expressionNoStringLottie expression for dynamic values. Takes precedence over value and keyframes.

* Either value or keyframes must be provided, but not both.

Rule Types

Color Rule

Overrides color properties (fill color, stroke color, text color).

FieldTypeDescription
value[R, G, B] (0–1 normalized per channel)Static color. e.g. [1, 0, 0] for red.
keyframesColor Keyframe[]Animated color transitions.

Color Keyframe

FieldRequiredTypeDescription
frameYesNumberAnimation frame number where this color is applied.
valueYes[R, G, B] (0–1 normalized)Color at this keyframe.
inTangentNo{ x: number|number[], y: number|number[] }Incoming Bézier easing handle.
outTangentNo{ x: number|number[], y: number|number[] }Outgoing Bézier easing handle.
holdNoBooleanIf true, hold value without interpolating.

Example: Static Color

{
  "id": "fill_color",
  "type": "Color",
  "value": [0.0, 0.47, 1.0]
}

Example: Animated Color

{
  "id": "background",
  "type": "Color",
  "keyframes": [
    { "frame": 0, "value": [1, 1, 1] },
    { "frame": 30, "value": [0.12, 0.12, 0.12] }
  ]
}

Scalar Rule

Overrides single-value numeric properties (opacity, stroke width, rotation, etc.).

FieldTypeDescription
valueNumberStatic numeric value.
keyframesScalar Keyframe[]Animated numeric values over time.

Scalar Keyframe

FieldRequiredTypeDescription
frameYesNumberAnimation frame number.
valueYesNumberNumeric value at this keyframe.
inTangentNo{ x: number|number[], y: number|number[] }Incoming Bézier easing handle.
outTangentNo{ x: number|number[], y: number|number[] }Outgoing Bézier easing handle.
holdNoBooleanIf true, hold value without interpolating.

Example

{
  "id": "icon_opacity",
  "type": "Scalar",
  "value": 75
}

Position Rule

Overrides position properties (position, anchor point, gradient start/end point).

FieldTypeDescription
value[x, y] or [x, y, z]Static position coordinates.
keyframesPosition Keyframe[]Animated position over time.

Position Keyframe

FieldRequiredTypeDescription
frameYesNumberAnimation frame number.
valueYes[x, y] or [x, y, z]Position at this keyframe.
inTangentNo{ x: number|number[], y: number|number[] }Incoming Bézier easing handle.
outTangentNo{ x: number|number[], y: number|number[] }Outgoing Bézier easing handle.
holdNoBooleanIf true, hold value without interpolating.
valueInTangentNoNumber[]Tangent for curved path movement.
valueOutTangentNoNumber[]Tangent for curved path movement.

Example

{
  "id": "element_position",
  "type": "Position",
  "value": [100, 200]
}

Vector Rule

Overrides vector properties (scale, size).

FieldTypeDescription
value[x, y]Static vector value.
keyframesVector Keyframe[]Animated vector over time.

Vector Keyframe

FieldRequiredTypeDescription
frameYesNumberAnimation frame number.
valueYes[x, y]Vector at this keyframe.
inTangentNo{ x: number|number[], y: number|number[] }Incoming Bézier easing handle.
outTangentNo{ x: number|number[], y: number|number[] }Outgoing Bézier easing handle.
holdNoBooleanIf true, hold value without interpolating.

Example

{
  "id": "icon_scale",
  "type": "Vector",
  "value": [1.5, 1.5]
}

Gradient Rule

Overrides gradient properties with a list of color stops.

FieldTypeDescription
valueGradient Stop[]Static gradient color stops.
keyframesGradient Keyframe[]Animated gradient over time.

Gradient Stop

FieldRequiredTypeDescription
colorYes[R, G, B] (0–1 normalized)Color at this stop.
offsetYesNumber (0–1)Stop position along the gradient (0 = start).

Gradient Keyframe

FieldRequiredTypeDescription
frameYesNumberAnimation frame number.
valueYesGradient Stop[]Gradient stops at this frame.
holdNoBooleanIf true, hold without interpolating.

Example

{
  "id": "background_gradient",
  "type": "Gradient",
  "value": [
    { "color": [0.0, 0.0, 0.5], "offset": 0 },
    { "color": [0.0, 0.5, 1.0], "offset": 1 }
  ]
}

Image Rule

Replaces an image asset in the animation.

FieldTypeDescription
valueImage ValueReplacement image details.

Image Value

FieldRequiredTypeDescription
idYesStringAsset identifier.
widthYesNumberImage width in pixels.
heightYesNumberImage height in pixels.
urlYesStringURL or path to the replacement image.

Example

{
  "id": "logo_image",
  "type": "Image",
  "value": {
    "id": "brand_logo",
    "width": 200,
    "height": 100,
    "url": "i/brand_logo.png"
  }
}

Text Rule

Overrides text document properties.

FieldTypeDescription
valueText objectReplacement text and style properties

Text rule values can include: text content, font family, font size, fill color, stroke color, styling (bold, italic), and alignment.

Example

{
  "id": "headline_text",
  "type": "Text",
  "value": {
    "t": "Hello World",
    "s": 48,
    "fc": [1, 1, 1]
  }
}

Expression System

The expression field on any rule enables dynamic values using Lottie expressions. Expressions take precedence over both value and keyframes.

Available globals:

  • time — Current animation time in seconds

  • value — Original property value from the Lottie animation

  • thisComp — Reference to the current composition

  • thisLayer — Reference to the current layer

All expressions must return a value via $bm_rt:

var $bm_rt;
$bm_rt = calculatedValue;

Example: Time-based color animation

{
  "id": "background_color",
  "type": "Color",
  "expression": "var $bm_rt; var t = Math.sin(time * 2); $bm_rt = [0.5 + t * 0.5, 0.3, 0.8];"
}

For comprehensive expression documentation, refer to the Lottie Expressions Documentation.

System Behavior

  • SetTheme actions require the theme to exist in the manifest and be compatible with the current animation

  • Dynamic theme loading and theme inheritance are not supported

  • Theme changes apply to the renderer immediately

  • Unknown themes are rejected during validation

  • Named colors (e.g. CSS color names) are not supported in Color rules; use normalized [R, G, B] arrays

References

Last updated: April 10, 2026 at 9:12 AMEdit this page