Skip to content

Lottie Player

Play Lottie animations with shared speed controls, theme colors and reduced-motion support.

import { LottiePlayer } from '@youj/motion/players'

Experimental: what this label means

Installation & usage

npm i @youj/motion @lottiefiles/dotlottie-react@^0.19.16

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use it for illustrated moments a designer animated in After Effects or the Lottie editor: a success mark, a loader with character, an empty-state illustration, a logo sting. For interface motion such as presses, toggles and layout, use Youj's primitives and icons instead. They're lighter, and they respond to input mid-flight.

Give it a file and a size. The player fills its box and keeps the animation's aspect ratio (fit="contain").

import { LottiePlayer } from '@youj/motion/players'

export function PaymentConfirmed() {
  return <LottiePlayer src="/animations/success-check.json" autoplay label="Payment confirmed" className="size-20" />
}

src takes a URL to a .lottie or Lottie .json file. To bundle the animation instead of fetching it, pass data: the parsed JSON, a JSON string or an ArrayBuffer of a .lottie file.

The examples above play sample files from /samples/. npx @youj/cli add lottie-samples copies the two .json ones into your app's public/samples/, so the examples run as they are; logo-sting.lottie is binary, so it isn't in the item.

Layout

fit decides how the animation fills the box: contain (the default), cover, fill, none, fit-width or fit-height. align places it inside the box as [x, y] fractions from 0 to 1, and it's centered by default.

Reference

Propssrc, data, autoplay… (18)

Props

LottiePlayer props
PropType
srcstring

URL of a .lottie or Lottie .json file.

–
datastring | ArrayBuffer | Record<string, unknown>

Inline animation data, instead of src.

–
autoplayboolean

Play once loaded and in view.

default false

false
loopboolean

default false

false
playOnHoverboolean

Hover (or focus within) plays forward; leaving plays back in reverse from wherever it is.

default false

false
playOnViewboolean

Start playing the first time the player scrolls into view.

default false

false
segment[number, number]

Restrict playback to a frame range, e.g. [0, 30].

–
playingboolean

Controlled playback. Overrides autoplay / playOnView / playOnHover while defined.

–
speednumber

Playback rate before time-scaling. The effective speed is speed / timeScale.

default 1

1
posterFrameLottieFrame

Frame shown when motion is reduced.

default 'last'

'last'
slotsRecord<string, string>

Color slot bindings: slot id → youj color token ('accent', 'fg-muted'…) or any CSS color expression. Slots whose id is itself a token name bind automatically, so youj samples need no mapping.

–
themedboolean

Follow youj color tokens and live theme changes.

default true

true
fitFit
'contain''cover''fill''none''fit-width''fit-height'

default 'contain'

'contain'
align[number, number]

Alignment in the box as [x, y] in 0–1. Default centered.

–
labelstring

Accessible name. Without it the player is decorative (aria-hidden).

–
onComplete() => void–
onLoad(player: DotLottie) => void–
onError(error: Error) => void

A load failed: the file couldn't be fetched, or isn't a Lottie or dotLottie animation.

–
Other props pass through: extends ComponentProps<'div'>.
PerformanceThe player renders with the dotLottie runtime, which loads its…

Performance

The player renders with the dotLottie runtime, which loads its WebAssembly from a CDN the first time a player mounts. To serve it yourself, call setWasmUrl from @lottiefiles/dotlottie-react before any player mounts. The canvas resizes with its box, and playback pauses while the player is offscreen.

MotionPlayback, hover out · reduced motion

Motion

Motion tokens
MomentTokens
Playbackthe file’s own timeline
no token

speed ÷ time scale

speed ÷ time scale
Hover outplayOnHover, reversing from the current frame
no token

same rate, reversed

same rate, reversed

Reduced motion

Never plays. It shows the poster frame, by default the last one: the resolved state, such as the finished check.

The timing lives in the file, so the player can't put it on Youj's tokens. It does keep the rest of the contract: the Speed control slows it, reduced motion stops it, and it pauses offscreen. The Youj samples on this page were generated from the motion tokens, so their curves match the rest of the system.

Reduced motion

Nothing plays. The player shows posterFrame, which defaults to 'last', the resolved state: the check fully drawn, the logo complete. Pass 'first' or a frame number for animations whose last frame isn't the meaningful one. Within a segment, 'first' and 'last' are the segment's ends. Switch on Reduced motion in any preview above to compare.

AccessibilityARIA, focus, announcements

Accessibility

  • Without label, the player is decorative and aria-hidden. With label, it's an image (role="img") with that name. Label an animation only when it carries meaning that isn't in the text beside it.
  • An animation isn't an announcement. When it marks a change, like a payment going through, announce the change in a live region too. The checkout preview uses role="status".
  • Keep focus with the task. When the control that was focused disappears with its view, move focus to the new view. The checkout preview moves it to the confirmation.