@deriv-com/quill-motion-web
v1.0.4
Published
Video/motion asset URLs for Deriv's Quill design system, synced from Frontify.
Maintainers
Readme
@deriv-com/quill-motion-web
Video and motion assets for Deriv's Quill design system, synced from Frontify.
This package ships URLs, not video files. The assets themselves live on
Frontify's CDN (media.ffycdn.net, CloudFront-backed, cached for a year), so
installing this package costs kilobytes no matter how many animations exist.
pnpm add @deriv-com/quill-motion-webJust give me the URL
import { onboardingWelcome } from '@deriv-com/quill-motion-web'
<video src={onboardingWelcome} autoPlay muted loop playsInline />Every export is a plain string constant, so unused ones tree-shake away
completely. This entry point does not require React — it works in Vue,
Svelte, plain HTML, or an og:video meta tag.
When the name is dynamic
import { motionAssets, type MotionName } from '@deriv-com/quill-motion-web'
function play(name: MotionName) {
const asset = motionAssets[name]
return <video src={asset.url} width={asset.width} height={asset.height} />
}MotionName is a union of every available asset, so a typo fails at build time
rather than 404-ing in production. Each record carries
{ url, posterUrl?, width?, height?, durationMs?, mimeType }. Passing width
and height through is worth doing — without them the browser cannot reserve
space before the video's metadata downloads, and the page shifts.
The React component
import { QuillMotion } from '@deriv-com/quill-motion-web/react'
<QuillMotion name="onboarding-welcome" alt="Welcome animation" />Renders a <video> with the defaults that are easy to get wrong:
| Default | Why |
|---|---|
| muted, playsInline | Mandatory. Without either, autoplay is blocked on iOS Safari and Chrome and the animation silently never starts on mobile. |
| preload="metadata" | Fetches dimensions without pulling the whole file. |
| autoPlay, loop | The common case for UI motion. |
| width, height | Set from the asset's intrinsic size to prevent layout shift. |
Every prop is overridable and any extra <video> attribute passes through:
<QuillMotion name="onboarding-welcome" alt="Welcome" loop={false} className="rounded-lg" />alt is required
Not an oversight. It is the only thing that makes the reduced-motion fallback and screen readers work, and it cannot be derived from the asset.
Reduced motion is handled for you
When the user's OS sets prefers-reduced-motion: reduce, QuillMotion renders
the poster still as an <img> instead of an autoplaying loop. Autoplaying video
is exactly what that setting exists to suppress — for users with vestibular
disorders it can cause real nausea. If an asset has no poster, the component
renders an empty box at the correct size rather than falling back to video.
Requires React 18+ (useSyncExternalStore), so the preference is correct on
the server's first paint rather than after a frame of autoplaying video.
Group subpaths
Assets are grouped by their Frontify folder:
import { welcome } from '@deriv-com/quill-motion-web/onboarding'How this package is updated
Generated by the Frontify sync — see
docs/superpowers/specs/2026-08-07-frontify-motion-pipeline-design.md.
Do not hand-edit src/groups/, src/assets.ts, or src/index.ts; a sync
overwrites them.
Removed and renamed assets are deprecated, never deleted — the old export
survives as a @deprecated alias, so a rename in Frontify cannot break your
build.
