
creator-plugin-development
Use when creating or modifying LottieFiles Creator Plugins with the Creator Plugin API. Covers plugin sandbox/UI architecture, message passing, scene graph manipulation, assets, storage, animation, and plugin development workflows.
- Installs
- 49
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/lottiefiles/creator-plugin-skills --skill creator-plugin-development- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads creator-plugin-development automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Creator Plugin Development
Creator Plugins extend the LottieFiles Creator animation application. They have a two-part sandboxed architecture:
- Plugin Sandbox (
plugin/plugin.ts) — Runs in isolation with access to thecreatorglobal API. Can manipulate scenes, layers, shapes, keyframes. Cannot make network requests. - UI (
src/) — Standard React application rendered in an iframe. Can make network requests viafetch. Cannot access thecreatorAPI.
The two parts communicate exclusively via message passing.
Project Structure
my-plugin/
├── plugin/
│ ├── manifest.json # Plugin metadata (id, name, apiVersion, entry, ui)
│ ├── plugin.ts # Sandbox code — has `creator` API access
│ └── [helpers].ts # Optional helper modules
├── src/
│ ├── main.tsx # React DOM entry point
│ ├── app.tsx # Main UI component
│ └── components/ # React components
├── vite.config.ts # Uses @lottiefiles/vite-plugin-creator
├── tsconfig.json # Root config with references
├── tsconfig.plugin.json # Plugin sandbox TypeScript config (no DOM)
├── tsconfig.app.json # UI TypeScript config (DOM + JSX)
├── index.html # Vite app template
└── package.json
tsconfig.plugin.json compiles sandbox code (no DOM libs). tsconfig.app.json compiles UI code (DOM + JSX).
The plugin manifest (plugin/manifest.json) defines the plugin's identity and entry points:
{
"id": "unique-uuid-v4",
"name": "My Plugin",
"apiVersion": "1",
"entry": "plugin.js",
"ui": "ui.html"
}
Development Commands
npm create @lottiefiles/creator-plugin@latest my-plugin # Scaffold a new plugin
# From the plugin directory (e.g., plugins/my-plugin/):
npm run dev # Start dev server with HTTPS hot-reload
npm run build # TypeScript check + Vite production build
npm exec tsc -- -b # Type check (run before completing any task)
To load in Creator: Plugins > Develop > New plugin > enter the localhost URL from npm run dev.
Communication Pattern (Critical)
This is the most common source of bugs. The message wrapping is asymmetric:
UI to Plugin
// In UI code (src/app.tsx) — MUST wrap in pluginMessage object
parent.postMessage(
{ pluginMessage: { type: 'create-shape', color: '#ff0000' } },
'*'
);
Plugin Receives Message
// In plugin sandbox (plugin/plugin.ts) — messages arrive unwrapped
creator.ui.onMessage((msg) => {
if (msg.type === 'create-shape') {
// Use creator API here
}
});
Plugin to UI
// In plugin sandbox — no wrapping needed
creator.ui.postMessage({ type: 'shape-created', layerId: layer.id });
UI Receives Message
// In UI code — messages arrive wrapped in pluginMessage
window.addEventListener('message', (event) => {
const message = event.data.pluginMessage;
if (message?.type === 'shape-created') {
// Handle response
}
});
Type-Safe Messages
Define shared message types to catch mismatches at compile time:
// shared/types.ts
export type PluginMessage =
| { type: 'create-shape'; color: string }
| { type: 'import-svg'; content: string }
| { type: 'delete-selection' };
For request/response tracking, include a messageId field.
Key API Patterns
Initialize Plugin
creator.ui.show({ width: 300, height: 500 });
Scene Access
const scene = creator.activeScene;
scene.size; // { width, height }
scene.duration; // seconds
scene.framerate; // FPS
scene.layers; // ReadonlyArray<Layer>
Create Shapes
const layer = creator.activeScene.createShapeLayer();
const rect = layer.createRectangle({ size: { width: 200, height: 150 } });
layer.createFill({ type: 'SOLID', color: { r: 66, g: 133, b: 244 } });
Import Assets
// From URL
const anim = await scene.import({ type: 'LOTTIE', url: 'https://...' });
const img = await scene.import({ type: 'IMAGE', url: 'https://...' });
const svg = await scene.import({ type: 'SVG', url: 'https://...' });
// From content string
const svgLayer = await scene.import({ type: 'SVG', content: svgString });
// Audio, from a URL or base64 content
const audio = await scene.import({ type: 'AUDIO', content: base64Audio });
LOTTIE and SVG imports return SceneLayer. IMAGE imports return ImageLayer. AUDIO imports return AudioLayer. A failed import rejects, so wrap scene.import() in try/catch.
Animate Properties
layer.position.addKeyframes([
{ frame: 0, value: { x: 100, y: 100 } },
{ frame: 60, value: { x: 400, y: 100 } },
]);
// With easing
const easeInOut = { type: 'CUBIC_BEZIER', x1: 0.42, y1: 0, x2: 0.58, y2: 1 };
layer.position.addKeyframes([
{ frame: 0, value: { x: 50, y: 100 }, easing: easeInOut },
{ frame: 60, value: { x: 350, y: 100 } },
]);
Selection
const selectedNodes = creator.selection.nodes;
creator.on('selection:nodes', (nodes) => {
creator.ui.postMessage({ type: 'selection-changed', count: nodes.length });
});
Node Type Checking
Always check node types before operations, and skip types you do not support. scene.layers, creator.selection.nodes, selection:nodes, shapes and creator.assets can return types your plugin does not know about, including types newer than your installed API types. See "Unknown Node Types" in references/scene-graph-and-nodes.md:
const layers = creator.selection.nodes;
layers.forEach((node) => {
if (node.type === 'SHAPE_LAYER') {
// Shape layer operations (has .shapes, .fills, .strokes, .trimPaths)
} else if (node.type === 'IMAGE_LAYER') {
// Image layer operations (has .image)
} else if (node.type === 'SCENE_LAYER') {
// Scene layer operations (has .scene, .break())
} else if (node.type === 'TEXT_LAYER') {
// Text layer operations (has .text, .fontFamily, .fontStyle, .fontSize,
// .alignment, .fill/.createFill, .stroke/.createStroke)
} else if (node.type === 'NULL_LAYER') {
// Null layer operations (transform only, has .layers)
} else if (node.type === 'AUDIO_LAYER') {
// Audio layer operations (has .audio, .muted, .volume; no transform)
}
// Any other type: skip it
});
Audio layers have no transform. Before reading position, opacity, or other transform members on a layer from scene.layers or the selection, check its type or use creator.utils.isTransformableLayer(layer). See references/scene-graph-and-nodes.md.
Network Requests
The plugin sandbox cannot make fetch requests. Use this pattern:
- UI fetches data from external API
- UI sends data to plugin via
parent.postMessage({ pluginMessage: ... }, '*') - Plugin processes data and applies to scene
For complete examples, see references/network-and-libraries.md.
Common Pitfalls
- Missing
pluginMessagewrapper — UI-to-plugin messages MUST be wrapped:{ pluginMessage: { ... } }. Plugin-to-UI messages do NOT need wrapping. - Fetching from plugin sandbox — Network requests only work in UI code. Move
fetchcalls tosrc/. - Using
localStorage/sessionStorage— The sandboxed iframe blocks browser storage APIs. Usecreator.clientStoragefrom plugin code instead. - Not checking node types — Always verify
node.typebefore accessing type-specific properties. - Setting
staticValueon animated properties — SettingstaticValuewhen keyframes exist will not affect the animation. Clear keyframes first or modify keyframe values directly. - Invisible shapes — Shapes need a fill or stroke to be visible. After
createRectangle(), callcreateFill(). - Scale values are percentages —
100= 100% scale (not1.0). Use{ x: 100, y: 100 }for normal size. - Opacity is 0-100 — Not 0-1. Use
100for fully opaque. - Color values are 0-255 — RGB channels use the range
{ r: 0-255, g: 0-255, b: 0-255 }. - Not calling
creator.ui.show()early — Call it at the top ofplugin.ts, before setting up message handlers. - Sending messages before UI is ready —
creator.ui.postMessage()right aftercreator.ui.show()will be dropped because the iframe hasn't loaded. Use a "ui-ready" handshake: have the UI send{ type: 'ui-ready' }on mount, then send data from the plugin only after receiving that message. - Assuming every layer has a transform — Audio layers have no
visible,position,scale,rotation, oropacity. Code that walksscene.layersand reads those members fails to compile, and throws at runtime on a project with audio. Filter by type first, and skip types you do not handle.
Verification Checklist
Before considering a task complete:
- Run
npm exec tsc -- -b— fix all type errors - Test message flow: UI sends > plugin receives > plugin responds > UI receives
- Confirm network requests are made from UI code, not plugin sandbox
- Verify
pluginMessagewrapping is correct in both directions
Reference Guide
For deeper information, consult these reference files as needed:
| Reference | When to Consult |
|---|---|
references/architecture-and-communication.md | Detailed architecture, complete message passing examples, UI API |
references/scene-graph-and-nodes.md | Scene hierarchy, node types, traversal patterns |
references/shapes-styling-animation.md | Creating shapes, fills/strokes/gradients, keyframes, easing |
references/importing-assets.md | LOTTIE/SVG/IMAGE/AUDIO import formats and patterns |
references/storage-and-events.md | clientStorage, node data, selection events, timeline API |
references/network-and-libraries.md | Fetch-from-UI pattern, using npm packages |
FAQ
What does the creator-plugin-development skill do?
Use when creating or modifying LottieFiles Creator Plugins with the Creator Plugin API. Covers plugin sandbox/UI architecture, message passing, scene graph manipulation, assets, storage, animation, and plugin development workflows.
How do I install creator-plugin-development?
Run npx skills add https://github.com/lottiefiles/creator-plugin-skills --skill creator-plugin-development in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/creator-plugin-development/ (personal) or .claude/skills/creator-plugin-development/ (project).
Which AI agents can use creator-plugin-development?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is creator-plugin-development safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains creator-plugin-development?
It is published by lottiefiles in lottiefiles/creator-plugin-skills. It has 49 recorded installs.
More from lottiefiles/creator-plugin-skills
creator-plugins-ui
lottiefiles/creator-plugin-skills
Open the skill to read its SKILL.md instructions.
Popular frontend & design skills
setup-matt-pocock-skills
mattpocock/skills
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
hyperframes-animation
heygen-com/hyperframes
All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.
prototype
mattpocock/skills
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.
vercel-react-best-practices
vercel-labs/agent-skills
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.